关于 java:使用 JDK 11 HttpClient 进行代理身份验证 | 珊瑚贝

Proxy Authentication with JDK 11 HttpClient


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

1
2
3
4
5
HttpClient httpClient = HttpClient.newBuilder()
        .version(HTTP_1_1)
        .proxy(ProxySelector.of(new InetSocketAddress(“proxy.mycompany.com”, 3128)))
        .authenticator(authenticator)
        .build();

,其中 authenticator 是:

1
2
3
4
5
6
Authenticator authenticator = new Authenticator() {
  @Override
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(“login”,“password”.toCharArray());
  }
};

然后我自己执行请求:

1
2
3
4
5
6
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());

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

我尝试过这里和这里提到的各种解决方案,但都没有帮助。

什么是让它工作的正确方法?

  • 它似乎在访问 http 站点时有效,但不是 https。您找到任何解决方案了吗?
  • @Keijack,对于那个特定的应用程序,我不得不使用 Apache HTTP 客户端,因为它是唯一能够处理 NTLM 身份验证的客户端。但我仍然想知道如何使它与 JDK HttpClient 一起工作。


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

1
2
3
4
5
6
7
8
9
10
11
12
13
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();

  • 在 System.setProperty(“jdk.http.auth.tunneling.disabledSchemes”??,””); 之后并且如果代理使用基本授权,则此方法有效。
  • @hbelmiro,最后我不得不使用另一个 HTTP 客户端,所以我没有检查你的答案。但还是谢谢你!
  • 我确认它适用于 Java 11,并假设系统属性”jdk.http.auth.tunneling.disabledSchemes”不包括”基本”。
  • 应该注意的是,这样做有效地绕过了 JDK 提供的 Authenticator API。由于基本身份验证非常简单,这是一个直接的解决方案。我观察到相同的行为,我很好奇为什么记录的解决方案不起作用,并将其追溯到我的公司代理服务器在 Proxy-Authenticate 标头中返回多个值,其中一个是 Basic 但 AuthenticationFilter.response() 会静默如果返回的第一个标头不是 Basic,则无法应用任何身份验证。


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

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

查看 jdk 8u111 发行说明

  • 它看起来像解决方案,但由于某种原因不起作用……我尝试使用相关的 jdk.http.auth.proxying.disabledSchemes 标志,但它也没有效果。
  • 代理和服务器是否都需要身份验证,如果需要,它们是否需要不同的凭据?如果是这种情况,那么您的身份验证器需要在返回适当的凭据之前考虑主机/地址。此外,您可能需要检查代理是否请求基本身份验证,因为这是堆栈默认支持的唯一方案。
  • 丹尼尔,是的,在这种特殊情况下,代理和服务器都需要身份验证。我尝试将调试器断点放入 Authenticator 代码中,但没有一个触发,因此它所针对的主机/地址没有区别。然后我深入研究了流量转储,发现目前这个代理不请求基本身份验证方案(但只请求 NTLM 和协商)。为了确认这一点,我使用了 Apache HTTP 客户端,它成功地处理了 NTLM 身份验证。将进一步调查。感谢您的时间!


来源:https://www.codenong.com/53333556/

微信公众号
手机浏览(小程序)

Warning: get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(): Failed to enable crypto in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(https://static.shanhubei.com/qrcode/qrcode_viewid_9774.jpg): failed to open stream: operation failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57
0
分享到:
没有账号? 忘记密码?