使用JDK 11 HttpClient的代理身份验证

时间:2018-11-16 07:52:39

标签: java http-proxy java-11 java-http-client

我正在尝试使用JDK 11 HttpClient通过公司代理发出请求,该公司代理需要通过登录名和密码进行身份验证。根据JDK的intro,我正在通过以下方式构建客户端实例:

HttpClient httpClient = HttpClient.newBuilder()
        .version(HTTP_1_1)
        .proxy(ProxySelector.of(new InetSocketAddress("proxy.mycompany.com", 3128)))
        .authenticator(authenticator)
        .build();

,其中authenticator是:

Authenticator authenticator = new Authenticator() {
  @Override
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication("login", "password".toCharArray());
  }
};

然后我自己执行请求:

HttpRequest outRequest = HttpRequest.newBuilder()
        .version(HTTP_1_1)
        .GET()
        .uri(URI.create("https://httpwg.org/asset/http.svg")) // no matter which URI to request
        .build();
HttpResponse<String> inResponse = httpClient.send(outRequest, BodyHandlers.ofString());

但是我没有收到来自目标服务器(https://httpwg.org的有效响应,而是收到了 HTTP 407(需要代理身份验证),即HttpClient不使用提供的{{1 }}。

我已经尝试过herehere提及的各种解决方案,但没有一个有帮助。

使其正常工作的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

您必须在请求上设置“代理授权”标头。

HttpClient httpClient = HttpClient.newBuilder()
        .version(HTTP_1_1)
        .proxy(ProxySelector.of(new InetSocketAddress("proxy.mycompany.com", 3128)))
        .build();

String encoded = new String(Base64.getEncoder().encode("login:password".getBytes()));

HttpRequest outRequest = HttpRequest.newBuilder()
                                    .version(HTTP_1_1)
                                    .GET()
                                    .uri(URI.create("https://httpwg.org/asset/http.svg")) // no matter which URI to request
                                    .setHeader("Proxy-Authorization", "Basic " + encoded)
                                    .build();

答案 1 :(得分:0)

默认情况下,从Java 8u111开始,通过身份验证代理进行隧道传输时,将禁用对代理的基本身份验证。

您可以通过在Java命令行上指定-Djdk.http.auth.tunneling.disabledSchemes=""来重新启用它。

请参见jdk 8u111 release notes