Re: Using SolrJ for digest authentication

2018-02-05 Thread ddramireddy
It's running only once. When request went from client from tomcat first-time,
tomcat sent response with "WWW-Authenticate" header with nonce value, asking
to complete the challenge. This challenge is processed. But apache http
client library is checking whether request is "repeatable" or not. This
validation is getting failed and following error is thrown.

"org.apache.http.client.NonRepeatableRequestException: Cannot retry request
with a non-repeatable request entity."

I am able to make POST call by directly calling apache http client library
with the following code. But, when I used solrj, I am getting this error.
"org.apache.http.client.NonRepeatableRequestException: Cannot retry request
with a non-repeatable request entity.". I can see solrj is setting
"isrepeatable" to false in httpsolrclient.java

Working code - When called directly using apache http library:

HttpHost target = HttpHost.create("localhost:9000");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(target.getHostName(), target.getPort()),
new UsernamePasswordCredentials("solr", "testpassword"));
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
try {

AuthCache authCache = new BasicAuthCache();
DigestScheme digestAuth = new DigestScheme();
digestAuth.overrideParamter("realm", "Solr");
authCache.put(target, digestAuth);

// Add AuthCache to the execution context
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);


HttpPost httpPost = new
HttpPost("http://localhost:9000/solr/account/update?commit=true;);
httpPost.setHeader("Content-type", "text/xml");
StringEntity stringEntity = new
StringEntity("*:*");
httpPost.getRequestLine();
httpPost.setEntity(stringEntity);
System.out.println("Executing request " +
httpPost.getRequestLine() + " to target " + target);
for (int i = 0; i < 3; i++) {
CloseableHttpResponse response =
httpclient.execute(httpPost, localContext);
try {
   
System.out.println("");
System.out.println(response.getStatusLine());
   
System.out.println(EntityUtils.toString(response.getEntity()));
} finally {
response.close();
}
}

} finally {
httpclient.close();
} 


Failing code:


public class TestSolrWithDigest {
public static void main(String[] args) {
try {
HttpSolrClient solrClient = initialiseSOLRClient();
try {

solrClient.deleteByQuery("account", "*:*");
UpdateResponse updateResponse =
solrClient.commit("account");
System.out.println(updateResponse.getStatus());
System.out.println("completed");
final ModifiableSolrParams pStatus = new
ModifiableSolrParams();
pStatus.add("qt", "/dataimport");

final QueryResponse resp = solrClient.query("account",
pStatus, SolrRequest.METHOD.GET);
System.out.println("status:" + resp.getStatus());

} catch (final SolrServerException | IOException exn) {

throw new IllegalStateException(exn);
}

} catch (Exception e) {
e.printStackTrace(System.err);
}


}

private static HttpSolrClient initialiseSOLRClient() {
URL solrURL = null;
try {
solrURL = new URL("http://localhost:9000/solr;);
} catch (MalformedURLException e) {
System.out.println("Cannot parse the SOLR URL!!" +
"http://localhost:9000/solr;);

}
String host = solrURL.getHost();
int port = solrURL.getPort();

AuthScope authScope = new AuthScope(host, port, "Solr", "Digest");

UsernamePasswordCredentials creds = new
UsernamePasswordCredentials("solr", "testpassword");

CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
authScope,
creds);

HttpClientBuilder builder = create();
builder.addInterceptorFirst(new PreemptiveAuthInterceptor());
builder.setDefaultCredentialsProvider(credsProvider);
CloseableHttpClient httpClient = builder.build();

return new HttpSolrClient.Builder()
.withBaseSolrUrl("http://localhost:9000/solr;)
.withHttpClient(httpClient)
.build();
}

static class PreemptiveAuthInterceptor implements HttpRequestInterceptor
{

public void process(final 

Using SolrJ for digest authentication

2018-01-31 Thread ddramireddy
We are currently deploying Solr in war mode(Yes, recommendation is not war.
But this is something I can't change now. Planned for future). I am setting
authentication for solr. As Solr provided basic authentication is not
working in Solr 6.4.2, I am setting up digest authentication in tomcat for
Solr. I am able to login into Solr admin application using credentials.

Now from my Java application, when I try to run a query, which will delete
documents in a core, it's throwing following error.

org.apache.http.client.NonRepeatableRequestException: Cannot retry request
with a non-repeatable request entity

I can see in HttpSolrClient, we are setting only basic authentication. But,
I am using Digest auth. Did anyone faced this error before??

This is my code:

public static void main(String[] args) throws ClassNotFoundException,
SQLException, InterruptedException, IOException, SolrServerException {
HttpSolrClient solrClient = getSolrHttpClient("solr",
"testpassword");

try {
solrClient.deleteByQuery("account", "*:*");
solrClient.commit("account");
} catch (final SolrServerException | IOException exn) {
throw new IllegalStateException(exn);
}
}

private static HttpSolrClient getSolrHttpClient(final String userName, final
String password) {

final HttpSolrClient solrClient = new HttpSolrClient.Builder()
.withBaseSolrUrl("http://localhost:9000/solr/index.html;)
.withHttpClient(getHttpClientWithSolrAuth(userName,
password))
.build();

return solrClient;
}

private static HttpClient getHttpClientWithSolrAuth(final String
userName, final String password) {
final CredentialsProvider provider = new BasicCredentialsProvider();
final UsernamePasswordCredentials credentials
= new UsernamePasswordCredentials(userName, password);
provider.setCredentials(AuthScope.ANY, credentials);


return HttpClientBuilder.create()
.addInterceptorFirst(new PreemptiveAuthInterceptor())
.setDefaultCredentialsProvider(provider)
.build();

}


static class PreemptiveAuthInterceptor implements HttpRequestInterceptor
{

DigestScheme digestAuth = new DigestScheme();

PreemptiveAuthInterceptor() {

}

@Override
public void process(final HttpRequest request, final HttpContext
context)
throws HttpException, IOException {
final AuthState authState = (AuthState)
context.getAttribute(HttpClientContext.TARGET_AUTH_STATE);

if (authState != null && authState.getAuthScheme() == null) {
final CredentialsProvider credsProvider =
(CredentialsProvider)
context.getAttribute(HttpClientContext.CREDS_PROVIDER);
final HttpHost targetHost = (HttpHost)
context.getAttribute(HttpCoreContext.HTTP_TARGET_HOST);
final Credentials creds = credsProvider.getCredentials(new
AuthScope(targetHost.getHostName(), targetHost.getPort(), "Solr",
"DIGEST"));
if (creds == null) {
System.out.println("No credentials for preemptive
authentication");
}
digestAuth.overrideParamter("realm", "Solr");
digestAuth.overrideParamter("nonce", Long.toString(new
Random().nextLong(), 36));
AuthCache authCache = new BasicAuthCache();
authCache.put(targetHost, digestAuth);

// Add AuthCache to the execution context
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);

request.addHeader(digestAuth.authenticate(creds, request,
localContext));
} else {
System.out.println("authState is null. No preemptive
authentication.");
}
}
}



--
Sent from: http://lucene.472066.n3.nabble.com/Solr-User-f472068.html