问题
I am trying to make a HttpClient to a service that support NTLM and Basic auth. In my case NTLM will not work, because the machine HttpClient is on is under a different domain to the service (thanks a corporate decision to very slowly migrate the name of the domain being used...). However it seems HttpClient will still try to use it anyway.
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(
username, password));
HttpClient client = HttpClientBuilder.create()
.setDefaultCredentialsProvider(credentialsProvider).build();
HttpGet method = new HttpGet(uri);
HttpResponse response = client.execute(method);
Severe: [WARN] HttpAuthenticator - NEGOTIATE authentication error: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)) Severe: [WARN] HttpAuthenticator - NTLM authentication error: Credentials cannot be used for NTLM authentication: org.apache.http.auth.UsernamePasswordCredentials
I just want it to send the HTTP Authentication: Basic ...
header. I have tested this outside any Java HTTP frameworks (e.g. using a raw ssl socket with a manually created HTTP request), so it seems to be some Java/Apache HTTP issue with it trying to do things I did not ask for and really don't want it to even try to do...
回答1:
However it seems HttpClient will still try to use it anyway.
That is because well behaved clients should choose a more secure scheme over an inherently insecure BASIC auth.
This is how one can disable NTLM (and other non-standard schemes) permanently
Registry<AuthSchemeProvider> r = RegistryBuilder.<AuthSchemeProvider>create()
.register(AuthSchemes.BASIC, new BasicSchemeFactory())
.register(AuthSchemes.DIGEST, new DigestSchemeFactory())
.build();
CloseableHttpClient client = HttpClients.custom()
.setDefaultAuthSchemeRegistry(r)
.build();
This is how one can force HttpClient to choose BASIC over NTLM on a per request basis
RequestConfig config = RequestConfig.custom()
.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC, AuthSchemes.NTLM))
.build();
HttpGet get = new HttpGet("/");
get.setConfig(config);
回答2:
This is not a full answer but more of a pointer:
In 4.x, (refer: http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/auth/AuthSchemeRegistry.html) class acts as the registry, you could unregister NTLM from there. (currently deprecated)
Another method could be to use preemptive HTTP authentication with Authorization header (use of preemptive auth. is debatable).
In 3.x it was easier (refer: http://hc.apache.org/httpclient-3.x/authentication.html)
来源:https://stackoverflow.com/questions/27442177/disable-ntlm-on-apache-httpclient-4-3-6