Index: java/org/apache/commons/httpclient/auth/DigestScheme.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/DigestScheme.java,v retrieving revision 1.6 diff -u -r1.6 DigestScheme.java --- java/org/apache/commons/httpclient/auth/DigestScheme.java 13 Aug 2003 19:57:10 -0000 1.6 +++ java/org/apache/commons/httpclient/auth/DigestScheme.java 1 Sep 2003 20:51:11 -0000 @@ -104,6 +104,22 @@ }; /** + * Gets an ID based upon the realm and the nonce value. This ensures that requests + * to the same realm with different nonce values will succeed. This differentiation + * allows servers to request re-authentication using a fresh nonce value. + */ + public String getID() { + + String id = getRealm(); + String nonce = getParameter("nonce"); + if (nonce != null) { + id += "-" + nonce; + } + + return id; + } + + /** * Constructor for the digest authentication scheme. * * @param challenge The authentication challenge Index: test/org/apache/commons/httpclient/TestAuthenticator.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestAuthenticator.java,v retrieving revision 1.28 diff -u -r1.28 TestAuthenticator.java --- test/org/apache/commons/httpclient/TestAuthenticator.java 12 Aug 2003 02:35:17 -0000 1.28 +++ test/org/apache/commons/httpclient/TestAuthenticator.java 1 Sep 2003 20:51:15 -0000 @@ -355,6 +355,39 @@ checkAuthorization(cred, method.getName(), method.getRequestHeader("Authorization").getValue()); } + public void testDigestAuthenticationWithStaleNonce() throws Exception { + + String headers = + "HTTP/1.1 401 OK\r\n" + + "Connection: close\r\n" + + "Content-Length: 0\r\n" + + "WWW-Authenticate: Digest realm=\"realm1\", nonce=\"ABC123\"\r\n"; + String headers2 = + "HTTP/1.1 401 OK\r\n" + + "Connection: close\r\n" + + "Content-Length: 0\r\n" + + "WWW-Authenticate: Digest realm=\"realm1\", nonce=\"321CBA\", stale=\"true\"\r\n"; + String headers3 = + "HTTP/1.1 200 OK\r\n" + + "Connection: close\r\n" + + "Server: HttpClient Test/2.0\r\n\r\n" + + "stuff\r\n"; + + SimpleHttpConnection conn = new SimpleHttpConnection(); + + conn.addResponse(headers); + conn.addResponse(headers2); + conn.addResponse(headers3); + HttpState state = new HttpState(); + UsernamePasswordCredentials cred = new UsernamePasswordCredentials("username","password"); + state.setCredentials(null, null, cred); + + SimpleHttpMethod method = new SimpleHttpMethod(); + method.setDoAuthentication(true); + assertEquals("Authentication failed", 200, method.execute(state, conn)); + checkAuthorization(cred, method.getName(), method.getRequestHeader("Authorization").getValue()); + } + public void testDigestAuthenticationWithMultipleRealms() throws Exception { String challenge1 = "Digest realm=\"realm1\""; String challenge2 = "Digest realm=\"realm2\"";