SEC-3: Add static method so digest-compatible passwords can be stored in database.

This commit is contained in:
Ben Alex 2005-11-25 05:20:57 +00:00
parent bb2ac126b7
commit 218fcf5b24
2 changed files with 102 additions and 35 deletions

View File

@ -114,10 +114,15 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
private AuthenticationDao authenticationDao;
private DigestProcessingFilterEntryPoint authenticationEntryPoint;
private UserCache userCache = new NullUserCache();
private boolean passwordAlreadyEncoded = false;
//~ Methods ================================================================
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
public void setPasswordAlreadyEncoded(boolean passwordAlreadyEncoded) {
this.passwordAlreadyEncoded = passwordAlreadyEncoded;
}
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
this.authenticationDao = authenticationDao;
}
@ -307,7 +312,7 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
String serverDigestMd5;
// Don't catch IllegalArgumentException (already checked validity)
serverDigestMd5 = generateDigest(username, realm,
serverDigestMd5 = generateDigest(passwordAlreadyEncoded, username, realm,
user.getPassword(),
((HttpServletRequest) request).getMethod(), uri, qop,
nonce, nc, cnonce);
@ -331,7 +336,7 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
userCache.putUserInCache(user);
// Don't catch IllegalArgumentException (already checked validity)
serverDigestMd5 = generateDigest(username, realm,
serverDigestMd5 = generateDigest(passwordAlreadyEncoded, username, realm,
user.getPassword(),
((HttpServletRequest) request).getMethod(), uri, qop,
nonce, nc, cnonce);
@ -377,6 +382,12 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
chain.doFilter(request, response);
}
public static String encodePasswordInA1Format(String username, String realm, String password) {
String a1 = username + ":" + realm + ":" + password;
String a1Md5 = new String(DigestUtils.md5Hex(a1));
return a1Md5;
}
/**
* Computes the <code>response</code> portion of a Digest authentication
* header. Both the server and user agent should compute the
@ -397,14 +408,19 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
*
* @throws IllegalArgumentException DOCUMENT ME!
*/
public static String generateDigest(String username, String realm,
public static String generateDigest(boolean passwordAlreadyEncoded, String username, String realm,
String password, String httpMethod, String uri, String qop,
String nonce, String nc, String cnonce) throws IllegalArgumentException {
String a1 = username + ":" + realm + ":" + password;
String a1Md5 = null;
String a2 = httpMethod + ":" + uri;
String a1Md5 = new String(DigestUtils.md5Hex(a1));
String a2Md5 = new String(DigestUtils.md5Hex(a2));
if (passwordAlreadyEncoded) {
a1Md5 = password;
} else {
a1Md5 = encodePasswordInA1Format(username, realm, password);
}
String digest;
if (qop == null) {

View File

@ -20,11 +20,14 @@ import junit.framework.TestCase;
import org.acegisecurity.DisabledException;
import org.acegisecurity.MockFilterConfig;
import org.acegisecurity.UserDetails;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.context.SecurityContextImpl;
import org.acegisecurity.providers.dao.AuthenticationDao;
import org.acegisecurity.providers.dao.UserCache;
import org.acegisecurity.providers.dao.UsernameNotFoundException;
import org.acegisecurity.util.StringSplitUtils;
import org.apache.commons.codec.binary.Base64;
@ -114,8 +117,8 @@ public class DigestProcessingFilterTests extends TestCase {
String nc = "00000002";
String cnonce = "c822c727a648aba7";
String password = "koala";
String responseDigest = DigestProcessingFilter.generateDigest(username,
realm, password, "GET", uri, qop, nonce, nc, cnonce);
String responseDigest = DigestProcessingFilter.generateDigest(false,
username, realm, password, "GET", uri, qop, nonce, nc, cnonce);
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);
@ -263,8 +266,8 @@ public class DigestProcessingFilterTests extends TestCase {
String nc = "00000002";
String cnonce = "c822c727a648aba7";
String password = "koala";
String responseDigest = DigestProcessingFilter.generateDigest(username,
realm, password, "GET", uri, qop, nonce, nc, cnonce);
String responseDigest = DigestProcessingFilter.generateDigest(false,
username, realm, password, "GET", uri, qop, nonce, nc, cnonce);
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
@ -307,8 +310,8 @@ public class DigestProcessingFilterTests extends TestCase {
String nc = "00000002";
String cnonce = "c822c727a648aba7";
String password = "koala";
String responseDigest = DigestProcessingFilter.generateDigest(username,
realm, password, "GET", uri, qop, nonce, nc, cnonce);
String responseDigest = DigestProcessingFilter.generateDigest(false,
username, realm, password, "GET", uri, qop, nonce, nc, cnonce);
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
@ -351,8 +354,8 @@ public class DigestProcessingFilterTests extends TestCase {
String nc = "00000002";
String cnonce = "c822c727a648aba7";
String password = "koala";
String responseDigest = DigestProcessingFilter.generateDigest(username,
realm, password, "GET", uri, qop, nonce, nc, cnonce);
String responseDigest = DigestProcessingFilter.generateDigest(false,
username, realm, password, "GET", uri, qop, nonce, nc, cnonce);
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
@ -395,8 +398,8 @@ public class DigestProcessingFilterTests extends TestCase {
String nc = "00000002";
String cnonce = "c822c727a648aba7";
String password = "koala";
String responseDigest = DigestProcessingFilter.generateDigest(username,
realm, password, "GET", uri, qop, nonce, nc, cnonce);
String responseDigest = DigestProcessingFilter.generateDigest(false,
username, realm, password, "GET", uri, qop, nonce, nc, cnonce);
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
@ -426,7 +429,8 @@ public class DigestProcessingFilterTests extends TestCase {
assertEquals(401, response.getStatus());
}
public void testNormalOperation() throws Exception {
public void testNormalOperationWhenPasswordIsAlreadyEncoded()
throws Exception {
Map responseHeaderMap = generateValidHeaders(60);
String username = "marissa";
@ -436,9 +440,10 @@ public class DigestProcessingFilterTests extends TestCase {
String qop = (String) responseHeaderMap.get("qop");
String nc = "00000002";
String cnonce = "c822c727a648aba7";
String password = "koala";
String responseDigest = DigestProcessingFilter.generateDigest(username,
realm, password, "GET", uri, qop, nonce, nc, cnonce);
String password = DigestProcessingFilter.encodePasswordInA1Format(username,
realm, "koala");
String responseDigest = DigestProcessingFilter.generateDigest(true,
username, realm, password, "GET", uri, qop, nonce, nc, cnonce);
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);
@ -466,8 +471,53 @@ public class DigestProcessingFilterTests extends TestCase {
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals("marissa",
((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal())
.getUsername());
((UserDetails) SecurityContextHolder.getContext().getAuthentication()
.getPrincipal()).getUsername());
}
public void testNormalOperationWhenPasswordNotAlreadyEncoded()
throws Exception {
Map responseHeaderMap = generateValidHeaders(60);
String username = "marissa";
String realm = (String) responseHeaderMap.get("realm");
String nonce = (String) responseHeaderMap.get("nonce");
String uri = "/some_file.html";
String qop = (String) responseHeaderMap.get("qop");
String nc = "00000002";
String cnonce = "c822c727a648aba7";
String password = "koala";
String responseDigest = DigestProcessingFilter.generateDigest(false,
username, realm, password, "GET", uri, qop, nonce, nc, cnonce);
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);
request.addHeader("Authorization",
createAuthorizationHeader(username, realm, nonce, uri,
responseDigest, qop, nc, cnonce));
request.setServletPath("/some_file.html");
// Launch an application context and access our bean
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"org/acegisecurity/ui/digestauth/filtertest-valid.xml");
DigestProcessingFilter filter = (DigestProcessingFilter) ctx.getBean(
"digestProcessingFilter");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig();
// Setup our expectation that the filter chain will be invoked
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Test
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals("marissa",
((UserDetails) SecurityContextHolder.getContext().getAuthentication()
.getPrincipal()).getUsername());
}
public void testOtherAuthorizationSchemeIsIgnored()
@ -535,8 +585,8 @@ public class DigestProcessingFilterTests extends TestCase {
String nc = "00000002";
String cnonce = "c822c727a648aba7";
String password = "koala";
String responseDigest = DigestProcessingFilter.generateDigest(username,
realm, password, "GET", uri, qop, nonce, nc, cnonce);
String responseDigest = DigestProcessingFilter.generateDigest(false,
username, realm, password, "GET", uri, qop, nonce, nc, cnonce);
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);
@ -566,8 +616,8 @@ public class DigestProcessingFilterTests extends TestCase {
// Now retry, giving an invalid nonce
password = "WRONG_PASSWORD";
responseDigest = DigestProcessingFilter.generateDigest(username, realm,
password, "GET", uri, qop, nonce, nc, cnonce);
responseDigest = DigestProcessingFilter.generateDigest(false, username,
realm, password, "GET", uri, qop, nonce, nc, cnonce);
request = new MockHttpServletRequest();
request.addHeader("Authorization",
@ -593,8 +643,9 @@ public class DigestProcessingFilterTests extends TestCase {
String nc = "00000002";
String cnonce = "NOT_SAME_AS_USED_FOR_DIGEST_COMPUTATION";
String password = "koala";
String responseDigest = DigestProcessingFilter.generateDigest(username,
realm, password, "GET", uri, qop, nonce, nc, "DIFFERENT_CNONCE");
String responseDigest = DigestProcessingFilter.generateDigest(false,
username, realm, password, "GET", uri, qop, nonce, nc,
"DIFFERENT_CNONCE");
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);
@ -635,8 +686,8 @@ public class DigestProcessingFilterTests extends TestCase {
String nc = "00000002";
String cnonce = "c822c727a648aba7";
String password = "WRONG_PASSWORD";
String responseDigest = DigestProcessingFilter.generateDigest(username,
realm, password, "GET", uri, qop, nonce, nc, cnonce);
String responseDigest = DigestProcessingFilter.generateDigest(false,
username, realm, password, "GET", uri, qop, nonce, nc, cnonce);
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);
@ -677,8 +728,8 @@ public class DigestProcessingFilterTests extends TestCase {
String nc = "00000002";
String cnonce = "c822c727a648aba7";
String password = "koala";
String responseDigest = DigestProcessingFilter.generateDigest(username,
realm, password, "GET", uri, qop, nonce, nc, cnonce);
String responseDigest = DigestProcessingFilter.generateDigest(false,
username, realm, password, "GET", uri, qop, nonce, nc, cnonce);
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);
@ -719,8 +770,8 @@ public class DigestProcessingFilterTests extends TestCase {
String nc = "00000002";
String cnonce = "c822c727a648aba7";
String password = "koala";
String responseDigest = DigestProcessingFilter.generateDigest(username,
realm, password, "GET", uri, qop, nonce, nc, cnonce);
String responseDigest = DigestProcessingFilter.generateDigest(false,
username, realm, password, "GET", uri, qop, nonce, nc, cnonce);
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);