Per RFC 7616, use the provided Response algorithm in the Request
For digest authentication, in RFC 7616 section "3.4 The Authorization Header Field": The values of the opaque and algorithm fields must be those supplied in the WWW-Authenticate response header field for the entity being requested. This commit honors that rule, and removes the previous behavior that augmented the request header with "algorithm=MD5" when none was provided in the server's response. Aside from the specification, it also stands to reason that if the server failed to provide "algorithm=..." in its "WWW-Authenticate" header, the server should be fine with the client failing to provide "algorithm=..." in the "Authorization" header. The motivation for this change is that including "algorithm=MD5" in the "Authorization" header causes http requests to fail when made to an embedded system, which I suspect to be a an Espressif ESP32 web server.
This commit is contained in:
parent
9ad56ad734
commit
d72a136817
|
@ -245,11 +245,7 @@ public class DigestScheme implements AuthScheme, Serializable {
|
|||
final String realm = this.paramMap.get("realm");
|
||||
final String nonce = this.paramMap.get("nonce");
|
||||
final String opaque = this.paramMap.get("opaque");
|
||||
String algorithm = this.paramMap.get("algorithm");
|
||||
// If an algorithm is not specified, default to MD5.
|
||||
if (algorithm == null) {
|
||||
algorithm = "MD5";
|
||||
}
|
||||
final String algorithm = this.paramMap.get("algorithm");
|
||||
|
||||
final Set<String> qopset = new HashSet<>(8);
|
||||
QualityOfProtection qop = QualityOfProtection.UNKNOWN;
|
||||
|
@ -278,7 +274,8 @@ public class DigestScheme implements AuthScheme, Serializable {
|
|||
|
||||
final Charset charset = AuthSchemeSupport.parseCharset(paramMap.get("charset"), defaultCharset);
|
||||
String digAlg = algorithm;
|
||||
if (digAlg.equalsIgnoreCase("MD5-sess")) {
|
||||
// If an algorithm is not specified, default to MD5.
|
||||
if (digAlg == null || digAlg.equalsIgnoreCase("MD5-sess")) {
|
||||
digAlg = "MD5";
|
||||
}
|
||||
|
||||
|
@ -317,7 +314,7 @@ public class DigestScheme implements AuthScheme, Serializable {
|
|||
a1 = null;
|
||||
a2 = null;
|
||||
// 3.2.2.2: Calculating digest
|
||||
if (algorithm.equalsIgnoreCase("MD5-sess")) {
|
||||
if ("MD5-sess".equalsIgnoreCase(algorithm)) {
|
||||
// H( unq(username-value) ":" unq(realm-value) ":" passwd )
|
||||
// ":" unq(nonce-value)
|
||||
// ":" unq(cnonce-value)
|
||||
|
@ -401,8 +398,9 @@ public class DigestScheme implements AuthScheme, Serializable {
|
|||
params.add(new BasicNameValuePair("nc", nc));
|
||||
params.add(new BasicNameValuePair("cnonce", cnonce));
|
||||
}
|
||||
// algorithm cannot be null here
|
||||
params.add(new BasicNameValuePair("algorithm", algorithm));
|
||||
if (algorithm != null) {
|
||||
params.add(new BasicNameValuePair("algorithm", algorithm));
|
||||
}
|
||||
if (opaque != null) {
|
||||
params.add(new BasicNameValuePair("opaque", opaque));
|
||||
}
|
||||
|
|
|
@ -247,6 +247,46 @@ public class TestDigestScheme {
|
|||
authscheme.generateAuthResponse(host, request, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDigestAuthenticationNoAlgorithm() throws Exception {
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
final HttpHost host = new HttpHost("somehost", 80);
|
||||
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
||||
.add(new AuthScope(host, "realm1", null), "username", "password".toCharArray())
|
||||
.build();
|
||||
|
||||
final String challenge = StandardAuthScheme.DIGEST + " realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge, null);
|
||||
|
||||
final String authResponse = authscheme.generateAuthResponse(host, request, null);
|
||||
|
||||
final Map<String, String> table = parseAuthResponse(authResponse);
|
||||
Assertions.assertNull(table.get("algorithm"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDigestAuthenticationMD5Algorithm() throws Exception {
|
||||
final HttpRequest request = new BasicHttpRequest("Simple", "/");
|
||||
final HttpHost host = new HttpHost("somehost", 80);
|
||||
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
||||
.add(new AuthScope(host, "realm1", null), "username", "password".toCharArray())
|
||||
.build();
|
||||
|
||||
final String challenge = StandardAuthScheme.DIGEST
|
||||
+ " realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\""
|
||||
+ ", algorithm=MD5";
|
||||
final AuthChallenge authChallenge = parse(challenge);
|
||||
final DigestScheme authscheme = new DigestScheme();
|
||||
authscheme.processChallenge(authChallenge, null);
|
||||
|
||||
final String authResponse = authscheme.generateAuthResponse(host, request, null);
|
||||
|
||||
final Map<String, String> table = parseAuthResponse(authResponse);
|
||||
Assertions.assertEquals("MD5", table.get("algorithm"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test digest authentication using the MD5-sess algorithm.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue