in sdk/core/azure-core-http/src/main/java/com/azure/android/core/http/util/AuthorizationChallengeHandler.java [258:295]
private String createDigestAuthorizationHeader(String method, String uri, Map<String, String> challenge,
String algorithm, Supplier<byte[]> entityBodySupplier, Function<byte[], byte[]> digestFunction) {
String realm = challenge.get(REALM);
String nonce = challenge.get(NONCE);
String qop = getQop(challenge.get(QOP));
String opaque = challenge.get(OPAQUE);
boolean hashUsername = Boolean.parseBoolean(challenge.get(USERHASH));
/*
* If the algorithm being used is <algorithm>-sess or QOP is 'auth' or 'auth-int' a client nonce will be needed
* to calculate the authorization header. If the QOP is set a nonce-count will need to retrieved.
*/
int nc = 0;
String clientNonce = null;
if (AUTH.equals(qop) || AUTH_INT.equals(qop)) {
clientNonce = generateNonce();
nc = getNc(challenge);
} else if (algorithm.endsWith(SESS)) {
clientNonce = generateNonce();
}
String ha1 = algorithm.endsWith(SESS)
? calculateHa1Sess(digestFunction, realm, nonce, clientNonce)
: calculateHa1NoSess(digestFunction, realm);
String ha2 = AUTH_INT.equals(qop)
? calculateHa2AuthIntQop(digestFunction, method, uri, entityBodySupplier.get())
: calculateHa2AuthQopOrEmpty(digestFunction, method, uri);
String response = (AUTH.equals(qop) || AUTH_INT.equals(qop))
? calculateResponseKnownQop(digestFunction, ha1, nonce, nc, clientNonce, qop, ha2)
: calculateResponseUnknownQop(digestFunction, ha1, nonce, ha2);
String headerUsername = (hashUsername) ? calculateUserhash(digestFunction, realm) : username;
return buildAuthorizationHeader(headerUsername, realm, uri, algorithm, nonce, nc, clientNonce, qop, response,
opaque, hashUsername);
}