简体   繁体   English

使用 JDK 11 HttpClient 进行代理身份验证

[英]Proxy Authentication with JDK 11 HttpClient

I'm trying to use JDK 11 HttpClient to make requests through a corporate proxy which requires authentication by login and password.我正在尝试使用 JDK 11 HttpClient通过公司代理发出请求,该代理需要通过登录名和密码进行身份验证。 According to JDK's intro , I'm building an instance of client by means of:根据JDK的介绍,我正在通过以下方式构建客户端实例:

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

, where authenticator is: ,其中authenticator者是:

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

And then I execute the request itself:然后我自己执行请求:

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());

But instead of valid response from the target server ( https://httpwg.org ) I receive HTTP 407 (Proxy Authentication Required) , ie HttpClient does not use the provided authenticator .但不是来自目标服务器的有效响应( https://httpwg.org )我收到HTTP 407(需要代理身份验证) ,即HttpClient不使用提供的authenticator器。

I've tried various solutions mentionedhere and here but none of them helped.我尝试了这里这里提到的各种解决方案,但没有一个有帮助。

What is the correct way to make it work?使它工作的正确方法是什么?

By default, basic authentication with the proxy is disabled when tunneling through an authenticating proxy since java 8u111.默认情况下,从 java 8u111 开始,当通过身份验证代理进行隧道传输时,将禁用使用代理的基本身份验证。

You can re-enable it by specifying -Djdk.http.auth.tunneling.disabledSchemes="" on the java command line.您可以通过在 java 命令行上指定-Djdk.http.auth.tunneling.disabledSchemes=""来重新启用它。

See the jdk 8u111 release notes请参阅jdk 8u111 发行说明

You have to set the "Proxy-Authorization" header on the request.您必须在请求上设置“代理授权”标头。

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();

Use利用

System.setProperty("jdk.http.auth.proxying.disabledSchemes", "");
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");

Construct your http client with proxy selector and authenticator使用代理选择器和身份验证器构建您的 http 客户端

HttpClient client = HttpClient.newBuilder()
    .authenticator(yourCustomAuthenticator)
    .proxy(yourCustomProxySelector)
    .build();

In your Authenticator override在您的身份验证器覆盖

@Override
protected PasswordAuthentication getPasswordAuthentication() {
    if (getRequestorType().equals(RequestorType.PROXY)) {
        return getPasswordAuthentication(getRequestingHost());
    } else {
        return null;
    }
}
protected PasswordAuthentication getPasswordAuthentication(String proxyHost) {
    // your logic to find username and password for proxyHost
    return new PasswordAuthentication(proxyUsername, proxyPassword.toCharArray());
    // or return null
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM