Re: Using SolrJ for digest authentication
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
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