Java HttpClient代理认证失败:getPasswordAuthentication()未被调用且返回407状态码
Java HttpClient代理认证失败:getPasswordAuthentication()未被调用且返回407状态码
我原本的代码用的是旧的HttpURLConnection类调用Web API,现在想换成HttpClient来实现PATCH请求(毕竟旧的Java HTTP类不支持PATCH方法)。
我这边是通过代理访问网络的,之前用HttpURLConnection的时候,只要把java.net.useSystemProxies属性设为true,就不用手动处理代理认证或者其他特殊配置。但换成HttpClient后,这个属性完全不起作用。我跟着好几个教程配置代理认证,但不管怎么弄,Authenticator的getPasswordAuthentication()方法从来没被调用过,请求还是一直返回407状态码。
下面是我用来测试的简化代码,始终过不了代理这一关:
public static void main(String[] args) { String url = "http://www.google.com/"; String proxyHost = "10.10.10.1"; int proxyPort = 8080; // 实际运行时用的是真实的账号密码 String authUser = "user"; String authPassword = "password"; ProxySelector proxySelector = ProxySelector.of(new InetSocketAddress(proxyHost, proxyPort)); Authenticator authenticator = new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(authUser, authPassword.toCharArray()); } }; HttpRequest.Builder builder = HttpRequest.newBuilder(); try { builder.uri(new URI(url)); } catch (URISyntaxException e) { e.printStackTrace(); } builder.method("GET", HttpRequest.BodyPublishers.noBody()); HttpRequest request = builder.build(); try (HttpClient client = HttpClient.newBuilder().proxy(proxySelector).authenticator(authenticator).build()) { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); System.out.println(response.body()); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } }
我是不是漏了什么配置导致代理认证失败?之前看到有问题提到要设置-Djdk.http.auth.tunneling.disabledSchemes="",但试了也没用。我打印了ProxySelector里的代理信息,显示是HTTP @ /10.10.10.1:8080,看起来是对的。另外我也参考过相关的代理认证配置方案,但都没解决问题,具体试过的方案包括:
- 给请求手动添加"Proxy-Authorization"头,结果还是无法通过代理认证
- 设置
jdk.http.auth.tunneling.disabledSchemes系统属性,没有效果 - 配置
ProxySelector和Authenticator,也就是上面代码里的做法,依然不行
折腾了几天后,我发现问题可能出在代理的认证方式上:这个代理用的是NTLM认证,而Java新版的HttpClient以及最新的Apache HttpComponents都已经不再支持NTLM了(毕竟微软自己也在逐步淘汰这种认证方式)。所以除非用旧版本的HTTP客户端代码,否则这个问题可能没办法解决。
备注:内容来源于stack exchange,提问作者jmohrmann
相关产品推荐
相关产品推荐

