我正在尝试为支持 NTLM 和基本身份验证的服务创建 HttpClient。在我的例子中,NTLM 将不起作用,因为 HttpClient 所在的机器与服务位于不同的域下(感谢公司决定非常缓慢地迁移正在使用的域的名称......)。然而,HttpClient 似乎仍会尝试使用它。
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
我只希望它发送 HTTP Authentication: Basic ...
header 。我已经在任何 Java HTTP 框架之外对此进行了测试(例如,使用带有手动创建的 HTTP 请求的原始 ssl 套接字),所以它似乎是一些 Java/Apache HTTP 问题,它试图做我没有要求并且真的没有做的事情甚至不希望它尝试做...
最佳答案
However it seems HttpClient will still try to use it anyway.
这是因为行为良好的客户端应该选择更安全的方案,而不是本质上不安全的 BASIC 身份验证。
这是永久禁用 NTLM(和其他非标准方案)的方法
Registry<AuthSchemeProvider> r = RegistryBuilder.<AuthSchemeProvider>create()
.register(AuthSchemes.BASIC, new BasicSchemeFactory())
.register(AuthSchemes.DIGEST, new DigestSchemeFactory())
.build();
CloseableHttpClient client = HttpClients.custom()
.setDefaultAuthSchemeRegistry(r)
.build();
这就是如何强制 HttpClient 在每个请求的基础上选择 BASIC 而不是 NTLM
RequestConfig config = RequestConfig.custom()
.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC, AuthSchemes.NTLM))
.build();
HttpGet get = new HttpGet("/");
get.setConfig(config);
关于java - 在 Apache HttpClient 4.3.6 上禁用 NTLM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27442177/