Search code examples
basic-authenticationjava-11java-http-client

How to do Preemptive authentication using Java 11 HTTP client?


I am trying to use Java 11 HTTP Client against an authenticated service, using Basic Authentication. The authentication occurs successfully but it makes an additional round-trip to the server, to understand it should send the authentication data.

Have searched around documentation and code and at some point internally it uses some kind of cache, but I am unable to set the cache value.

Here is my client code:

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("http://someurl.com"))
        .build();

HttpClient client = HttpClient.newBuilder()
        .authenticator(new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("user", "pass".toCharArray());
            }
        })
        .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

What I expected was that somehow I could tell the client to preemptively sent the authentication data, not only when the server requests.


Solution

  • The HttpClient behaves in the same way than HttpURLConnection in what preemptive authentication is concerned: for basic authentication it will preemptively send the credentials if it finds them in its cache. However, the cache is populated after the first successful request (or more exactly after the response headers indicating that the authentication was successful are parsed).

    If this is not satisfactory for you then a possibility is to handle authentication directly in your code by preemptively inserting the Authorization header in your request, and not setting any Authenticator.