简体   繁体   中英

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. According to JDK's intro , I'm building an instance of client by means of:

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 = 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 .

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.

You can re-enable it by specifying -Djdk.http.auth.tunneling.disabledSchemes="" on the java command line.

See the jdk 8u111 release notes

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

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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