//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

[[http-client-authentication]]
=== Authentication Support

Jetty's HTTP client supports the `BASIC` and `DIGEST` authentication mechanisms defined by link:https://tools.ietf.org/html/rfc7235[RFC 7235].

You can configure authentication credentials in the HTTP client instance as follows:

[source, java, subs="{sub-order}"]
----
URI uri = new URI("http://domain.com/secure");
String realm = "MyRealm";
String user = "username";
String pass = "password";

// Add authentication credentials
AuthenticationStore auth = httpClient.getAuthenticationStore();
auth.addAuthentication(new BasicAuthentication(uri, realm, user, pass));

ContentResponse response = httpClient
        .newRequest(uri)
        .send()
        .get(5, TimeUnit.SECONDS);
----

Jetty's HTTP client tests authentication credentials against the challenge(s) the server issues (see our section here on link:#configuring-security-secure-passwords[secure password obfuscation]), and if they match it automatically sends the right authentication headers to the server for authentication.
If the authentication is successful, it caches the result and reuses it for subsequent requests for the same domain and matching URIs.

The HTTP conversation for a successful match is the following:

----
Application  HttpClient                     Server
     |           |                             |
     |--- GET ---|------------ GET ----------->|
     |           |                             |
     |           |<-- 401 + WWW-Authenticate --|
     |           |                             |
     |           |--- GET + Authentication --->|
     |           |                             |
     |<-- 200 ---|------------ 200 ------------|
----

The application does not receive events related to the response with code 401, they are handled internally by `HttpClient` which produces a request similar to the original but with the correct `Authorization` header, and then relays the response with code 200 to the application.

Successful authentications are cached, but it is possible to clear them in order to force authentication again:

[source, java, subs="{sub-order}"]
----
httpClient.getAuthenticationStore().clearAuthenticationResults();
----

Authentications may be preempted to avoid the additional roundtrip due to the server challenge in this way:

[source, java, subs="{sub-order}"]
----
AuthenticationStore auth = httpClient.getAuthenticationStore();
URI uri = URI.create("http://domain.com/secure");
auth.addAuthenticationResult(new BasicAuthentication.BasicResult(uri, "username", "password"));
----

In this way, requests for the given URI are enriched by `HttpClient` immediately with the `Authorization` header, and the server should respond with a 200 and the resource content rather than with the 401 and the challenge.

It is also possible to preempt the authentication for a single request only, in this way:

[source, java, subs="{sub-order}"]
----
URI uri = URI.create("http://domain.com/secure");
Authentication.Result authn = new BasicAuthentication.BasicResult(uri, "username", "password")
Request request = httpClient.newRequest(uri);
authn.apply(request);
request.send();
----

See also the link:#http-client-proxy-authentication[proxy authentication section] for further information about how authentication works with HTTP proxies.
