Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8229962

java.net.http.HttpClient authentication does not work with proxy tunnel

XMLWordPrintable

    • x86_64
    • linux

      A DESCRIPTION OF THE PROBLEM :
      This bug only happens for a CONNECT proxy tunnel (e.g. https:// site via a proxy). The configured Authenticator is not called, no exception is thrown, and a "bare" HTTP 407 (with null response body) is returned to the user.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. start a fake proxy server that returns 407 on port 8000:
      printf "HTTP/1.0 407 Unauthorized\r\nProxy-Authenticate: Basic\r\nContent-Type: text/plain\r\n\r\nthis is a body" | nc -l 8000

      2. run the included java program
      java repro.java

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The program should print "Authenticator called" and then throw IOException of "No credentials provided":
      $ java repro.java
      Authenticator called!
      Exception in thread "main" java.io.IOException: No credentials provided
      ...

      You can also see correct behavior if you change the test case URI from "https://example.org" to "http://example.org" because it will not use a CONNECT tunnel and behavior there is correct.
      ACTUAL -
      $java repro.java
      HTTP_1_1 407 body=null


      ---------- BEGIN SOURCE ----------
      import java.net.http.*;
      import java.net.*;

      public class repro {
        public static void main(String args[]) throws Exception {
          HttpClient.Builder builder = HttpClient.newBuilder();
          builder.authenticator(new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
              System.out.println("Authenticator called!");
              return null;
            }
          });
          builder.proxy(ProxySelector.of(new InetSocketAddress("localhost", 8000)));
          HttpClient client = builder.build();
          HttpRequest request = HttpRequest.newBuilder(URI.create("https://example.org")).build();
          HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
          System.out.printf("%s %d body=%s\n", response.version(), response.statusCode(), response.body());
        }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Unfortunately there isn't an easy workaround I can find. I tried base64-encoding and setting "Proxy-Authorization: Basic xyz" header myself to bypass the authenticator api, but it doesn't get sent to the proxy.

      FREQUENCY : always


            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: