public final class DigestAuthentication
extends java.lang.Object
Create an instance of this class once a digest challenge is received. Use the instance to respond to the challenge and to authenticate future requests.
HttpURLConnection and, in case
 of a challenge, respond to the challenge:
 // Step 1. Create the connection URL url = new URL("http://httpbin.org/digest-auth/auth/user/passwd"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // Step 2. Make the request and check to see if the response contains an authorization challenge if (connection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) { // Step 3. Create a authentication object from the challenge... DigestAuthentication auth = DigestAuthentication.fromResponse(connection); // ...with correct credentials auth.username("user").password("passwd"); // Step 4 (Optional). Check if the challenge was a digest challenge of a supported type if (!auth.canRespond()) { // No digest challenge or a challenge of an unsupported type - do something else or fail return; } // Step 5. Create a new connection, identical to the original one. connection = (HttpURLConnection) url.openConnection(); // ...and set the Authorization header on the request, with the challenge response connection.setRequestProperty(DigestChallengeResponse.HTTP_HEADER_AUTHORIZATION, auth.getAuthorizationForRequest("GET", connection.getURL().getPath())); }
DigestAuthentication object can be used to authenticate future requests. This removes
 the need of making the request twice (once for the challenge and once for the actual request):
 HttpURLConnection anotherConnection = (HttpURLConnection) url.openConnection(); anotherConnection.setRequestProperty(DigestChallengeResponse.HTTP_HEADER_AUTHORIZATION, auth.getAuthorizationForRequest("GET", initialConnection.getURL().getPath()));
WwwAuthenticateHeader to
 parse WWW-Authenticate headers into individual challenges. Example:
 if (connection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) { // Parse the headers and extract challenges, this will return challenges of all types List<String> challengeStrings = WwwAuthenticateHeader.extractChallenges(connection.getHeaderFields()); // Check the challenges and act on them... // ...or pass them to DigestAuthentication to handle digest challenges: DigestAuthentication auth = DigestAuthentication.fromChallenges(challengeStrings).username("user").password ("passwd"); }
challengeOrdering(Comparator) to define
 which challenge is preferred.
 auth-int quality of protectionauth-int quality of protection requires a digest of the entity body of the
 request to be included in the challenge response. To be compatible with servers that require
 auth-int quality of protection, use
 getAuthorizationForRequest(String, String, byte[]) instead of
 getAuthorizationForRequest(String, String).
 
 auth-int is uncommon. It cannot be used with HTTP requests that does not include a
 body, such as GET. Some server implementations accept auth-int
 authentication for such requests as well, using a zero-length entity body.
 
| Modifier and Type | Field and Description | 
|---|---|
static java.util.Comparator<DigestChallenge> | 
DEFAULT_CHALLENGE_COMPARATOR
Default comparator used when comparing which challenge to use when there is more than one to
 choose from. 
 | 
| Modifier and Type | Method and Description | 
|---|---|
boolean | 
canRespond()
Returns  
true if a response can be generated to any of the challenges. | 
DigestAuthentication | 
challengeOrdering(java.util.Comparator<? super DigestChallenge> orderingComparator)
Sets the challenge ordering, which will determine which challenge that will be used if there
 are several. 
 | 
static DigestAuthentication | 
fromChallenges(java.lang.Iterable<java.lang.String> challenges)
Creates an authentication from a number of challenges. 
 | 
static DigestAuthentication | 
fromDigestChallenge(DigestChallenge challenge)
Creates an authentication from a parsed Digest challenge. 
 | 
static DigestAuthentication | 
fromDigestChallenges(java.lang.Iterable<? extends DigestChallenge> challenges)
Creates an authentication from a number of parsed Digest challenges. 
 | 
static DigestAuthentication | 
fromResponse(java.net.HttpURLConnection connection)
Creates an authentication by reading response headers from an  
HttpURLConnection object. | 
static <T extends java.lang.Iterable<java.lang.String>> | 
fromResponseHeaders(java.util.Map<java.lang.String,T> headers)
Creates an authentication from a map of HTTP response headers. 
 | 
static DigestAuthentication | 
fromWwwAuthenticateHeader(java.lang.String wwwAuthenticateHeader)
Creates an authentication from a single  
WWW-Authenticate header. | 
static DigestAuthentication | 
fromWwwAuthenticateHeaders(java.lang.Iterable<java.lang.String> wwwAuthenticateHeaders)
Creates an authentication from a number of  
WWW-Authenticate headers. | 
java.lang.String | 
getAuthorizationForRequest(java.lang.String requestMethod,
                          java.lang.String digestUri)
Returns the value of  
Authorization header that can be used in a particular
 request. | 
java.lang.String | 
getAuthorizationForRequest(java.lang.String requestMethod,
                          java.lang.String digestUri,
                          byte[] entityBody)
Returns the value of  
Authorization header that can be used in a particular
 request. | 
DigestChallengeResponse | 
getChallengeResponse()
Picks a challenge among the available challenges and generates a response to it. 
 | 
java.lang.String | 
getPassword()
Returns the password to use for authentication. 
 | 
java.lang.String | 
getUsername()
Returns the username to use for authentication. 
 | 
boolean | 
isEntityBodyDigestRequired()
Returns  
true if the digest of the entity-body is required to generate a
 response to the preferred challenge. | 
DigestAuthentication | 
password(java.lang.String password)
Sets the password to use for authentication. 
 | 
java.lang.String | 
toString()  | 
DigestAuthentication | 
username(java.lang.String username)
Sets the username to use for authentication. 
 | 
public static final java.util.Comparator<DigestChallenge> DEFAULT_CHALLENGE_COMPARATOR
Challenges that are not supported are ordered last.
 Challenges that use digest algorithms SHA-256 or SHA-256-sess are
 always preferred over challenges that use MD5, MD5-sess, or does
 not specify an algorithm.
 
If the rules above are not enough challenges are ordered according to the following, from most preferred to least preferred:
auth and
 auth-int.auth but not
 auth-int.auth-int and nothing else.
 This is ranked last among the supported challenges because auth-int is limited
 and cannot authenticate requests without a body, such as HTTP GET.public static DigestAuthentication fromResponse(java.net.HttpURLConnection connection) throws ChallengeParseException
HttpURLConnection object.connection - the connectionDigestAuthentication objectChallengeParseException - if challenges could not be parsedpublic static <T extends java.lang.Iterable<java.lang.String>> DigestAuthentication fromResponseHeaders(java.util.Map<java.lang.String,T> headers) throws ChallengeParseException
 A note about the map representing the headers: header names are case insensitive in HTTP, but
 keys in a Map are case-sensitive. This method uses
 WwwAuthenticateHeader.extractChallenges(Map) and handles case in the same way.
headers - the headers, as a map where the keys are header names and values are
                iterables where each element is a header value stringDigestAuthentication objectChallengeParseException - if challenges could not be parsedpublic static DigestAuthentication fromWwwAuthenticateHeaders(java.lang.Iterable<java.lang.String> wwwAuthenticateHeaders) throws ChallengeParseException
WWW-Authenticate headers.wwwAuthenticateHeaders - the WWW-Authenticate headersDigestAuthentication objectChallengeParseException - if challenges could not be parsedpublic static DigestAuthentication fromWwwAuthenticateHeader(java.lang.String wwwAuthenticateHeader) throws ChallengeParseException
WWW-Authenticate header.wwwAuthenticateHeader - the WWW-Authenticate headerDigestAuthentication objectChallengeParseException - if challenges could not be parsedpublic static DigestAuthentication fromChallenges(java.lang.Iterable<java.lang.String> challenges) throws ChallengeParseException
Challenges can be of any type, not just Digest challenges. See RFC 7235, Section 2.1 for a definition of challenges. Some example of valid challenges:
Basic realm="simple"Digest realm="testrealm@host.com", qop="auth,auth-int",
 nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
 opaque="5ccc069c403ebaf9f0171e9517f40e41"Newauth realm="apps", type=1, title="Login to \"apps\""challenges - the challengesDigestAuthentication objectChallengeParseException - if challenges could not be parsedpublic static DigestAuthentication fromDigestChallenges(java.lang.Iterable<? extends DigestChallenge> challenges)
challenges - the digest challengesDigestAuthentication objectpublic static DigestAuthentication fromDigestChallenge(DigestChallenge challenge)
challenge - the digest challengeDigestAuthentication objectpublic boolean canRespond()
true if a response can be generated to any of the challenges.
 
 If this method returns false, it could mean that:
 
DigestChallengeResponse.isChallengeSupported(DigestChallenge)).true if a response can be generated to any of the challengespublic DigestAuthentication challengeOrdering(java.util.Comparator<? super DigestChallenge> orderingComparator)
 By default, challenges are sorted using DEFAULT_CHALLENGE_COMPARATOR.
 
 This method must be called before a choice is made as to which challenge to use. Once a choice
 has been made it cannot be changed. This means that his method cannot be called after methods
 such as getChallengeResponse() or getAuthorizationForRequest(String, String).
orderingComparator - A comparator object that will be used to sort the challenges. The
                           challenge that will be used is the first supported challenge
                           according to the sort order defined by the comparator.java.lang.IllegalStateException - if this method is called after a method that requires a choice
                               to be made regarding which of the available challenges to use:
                               isEntityBodyDigestRequired(),
                               getChallengeResponse(),
                               getAuthorizationForRequest(String, String),
                               getAuthorizationForRequest(String, String, byte[]).public boolean isEntityBodyDigestRequired()
true if the digest of the entity-body is required to generate a
 response to the preferred challenge.
 
 For most challenges, setting the digest of the entity-body is optional. It is only
 required if the only quality of protection the server accepts is auth-int.
true if the digest of the entity-body must be setpublic DigestAuthentication username(java.lang.String username)
username - the usernamegetUsername(), 
Section 3.2.2 of RFC 2617public java.lang.String getUsername()
username(String)public DigestAuthentication password(java.lang.String password)
password - the passwordgetPassword()public java.lang.String getPassword()
password(String)public DigestChallengeResponse getChallengeResponse()
 The response returned references the internal representation of this instance, modifying it
 will modify this instance. Example: Calling
 username on the response will change the value
 returned by getUsername().
java.lang.IllegalStateException - if this method is called when
                               canRespond() returns false, that is, none of
                               the available challenges are supportedpublic java.lang.String getAuthorizationForRequest(java.lang.String requestMethod,
                                                   java.lang.String digestUri)
Authorization header that can be used in a particular
 request.
 
 The first time an Authorization header is generated nonce count will be set to 1.
 Each subsequent call will increase the nonce count by one. The server expects the nonce count
 to increase by exactly one for each request, so do not call this method unless you intend to
 use the result in a request.
 
 Calling this method has the same effect as calling
 getAuthorizationForRequest(String, String, byte[]) with a zero-length byte array for
 entityBody.
requestMethod - the HTTP request method, such as GET or POST.digestUri - the Request-URI of the Request-Line of the HTTP request,
                      see DigestChallengeResponse.digestUri(String) for a discussion
                      of what to set hereAuthorization headerjava.lang.IllegalStateException - If this method is called when
                                          canRespond() returns false, that
                                          is, none of the available challenges are supportedInsufficientInformationException - If username or password has not been setDigestChallengeResponse.requestMethod(String), 
DigestChallengeResponse.digestUri(String), 
getAuthorizationForRequest(String, String, byte[])public java.lang.String getAuthorizationForRequest(java.lang.String requestMethod,
                                                   java.lang.String digestUri,
                                                   byte[] entityBody)
Authorization header that can be used in a particular
 request.
 
 This method takes the request's entity-body as an argument. The entity body is the
 message body after decoding any transfer encoding that might have been applied. Example: If
 Transfer-Encoding is gzip the entity body is the unzipped message and
 the message body is the gzipped message. Only some requests have entity bodies,
 GET requests for example do not. See
 DigestChallengeResponse.entityBody(byte[]) for more details.
 
 This method can be used for any request, but the entity-body is only used for "quality of
 protection" auth-int. Quality of protection auth-int requires a
 hash of the entity body of the message to be included in the challenge response.
 
 Not all requests have an entity-body, for example, GET requests do not. Some
 servers accept an entity-body of zero length for such requests (even though it is
 strictly speaking not correct to do so).
 
 The first time an Authorization header is generated nonce count will be set to 1.
 Each subsequent call will increase the nonce count by one. The server expects the nonce count
 to increase by exactly one for each request, so do not call this method unless you intend to
 use the result in a request.
requestMethod - the HTTP request method, such as GET or POST.digestUri - the Request-URI of the Request-Line of the HTTP request,
                      see DigestChallengeResponse.digestUri(String) for a discussion
                      of what to set hereentityBody - the entity-body of the request (see above)Authorization headerjava.lang.IllegalStateException - If this method is called when
                                          canRespond() returns false, that
                                          is, none of the available challenges are supportedInsufficientInformationException - If username or password has not been setDigestChallengeResponse.requestMethod(String), 
DigestChallengeResponse.digestUri(String), 
DigestChallengeResponse.entityBody(byte[]), 
getAuthorizationForRequest(String, String), 
isEntityBodyDigestRequired()public java.lang.String toString()
toString in class java.lang.Object