mre
mre

Reputation: 113

Apache HttpClient, basic auth and session cookie

I want to call a web service that requires basic authentication. I cannot use preemptive authentication, because the service returns code 401 with a specific cookie. This cookie has to be sent in the response together with the basic auth header. The following code does not work:

    CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    Credentials credentials = new UsernamePasswordCredentials("user", "password");
    credentialsProvider.setCredentials(AuthScope.ANY, credentials);

    RequestConfig requestConfig = RequestConfig.custom()
            .setCookieSpec(CookieSpecs.DEFAULT)
            .build();

    HttpClient httpClient = HttpClientBuilder.create()
            .setDefaultCredentialsProvider(credentialsProvider)
            .setDefaultRequestConfig(requestConfig)
            .build();

    HttpGet get = new HttpGet("https://a.something.com/something");
    try {
        HttpResponse response = httpClient.execute(get);
        System.out.println(response.getStatusLine());
    } catch (IOException e) {
        e.printStackTrace();
    }

In the logs I can see that the HttpClient reacts to the code 401 and that it is sending the request a second time with basic auth data. But the cookie is missing:

http-outgoing-0 >> "GET /something HTTP/1.1[\r][\n]"
http-outgoing-0 >> "Host: a.something.com[\r][\n]"
http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_172)[\r][\n]"
http-outgoing-0 >> "[\r][\n]"
http-outgoing-0 << "HTTP/1.1 401 Unauthorized[\r][\n]"
http-outgoing-0 << "WWW-authenticate: basic realm="XXXXXX"[\r][\n]"
http-outgoing-0 << "Set-Cookie: SMCHALLENGE=YES; path=/; domain=.something.com; secure; HTTPOnly[\r][\n]"
http-outgoing-0 >> "GET /something HTTP/1.1[\r][\n]"
http-outgoing-0 >> "Host: a.something.com[\r][\n]"
http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_172)[\r][\n]"
http-outgoing-0 >> "Authorization: Basic xxxxxxxxxxxxxxx[\r][\n]"
http-outgoing-0 >> "[\r][\n]"
http-outgoing-0 << "HTTP/1.1 403 Forbidden[\r][\n]"

With the debugger I went until the following line: https://github.com/apache/httpcomponents-client/blob/6f4550ff977a8f497822a17115572dcdb6e715b6/httpclient/src/main/java/org/apache/http/impl/execchain/MainClientExec.java#L272

In this loop, the request gets executed the first time. Then, in line 293, the method "needsAuthentication()" returns true and the request gets executed a second time. But I don't see, where the cookies from the first response should be copied into the second request.

Upvotes: 1

Views: 1816

Answers (1)

mre
mre

Reputation: 113

After looking into MainClientExec.java (see above), I assume that this is either a bug or simply not a supported feature: Apache HttpClient does not set cookies in "401" retries.

Upvotes: 1

Related Questions