Add missing @Test attributes
This commit is contained in:
parent
236a4790c2
commit
3ce5ea7710
|
@ -15,42 +15,7 @@
|
|||
|
||||
package org.springframework.security.ui.digestauth;
|
||||
|
||||
import org.springframework.security.SpringSecurityMessageSource;
|
||||
import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.security.AuthenticationServiceException;
|
||||
import org.springframework.security.BadCredentialsException;
|
||||
|
||||
import org.springframework.security.context.SecurityContextHolder;
|
||||
|
||||
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.providers.dao.UserCache;
|
||||
import org.springframework.security.providers.dao.cache.NullUserCache;
|
||||
|
||||
import org.springframework.security.ui.AuthenticationDetailsSource;
|
||||
import org.springframework.security.ui.WebAuthenticationDetailsSource;
|
||||
|
||||
import org.springframework.security.userdetails.UserDetails;
|
||||
import org.springframework.security.userdetails.UserDetailsService;
|
||||
import org.springframework.security.userdetails.UsernameNotFoundException;
|
||||
|
||||
import org.springframework.security.util.StringSplitUtils;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.MessageSourceAware;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
|
@ -60,27 +25,58 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.MessageSourceAware;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.security.AuthenticationServiceException;
|
||||
import org.springframework.security.BadCredentialsException;
|
||||
import org.springframework.security.SpringSecurityMessageSource;
|
||||
import org.springframework.security.context.SecurityContextHolder;
|
||||
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.providers.dao.UserCache;
|
||||
import org.springframework.security.providers.dao.cache.NullUserCache;
|
||||
import org.springframework.security.ui.AuthenticationDetailsSource;
|
||||
import org.springframework.security.ui.WebAuthenticationDetailsSource;
|
||||
import org.springframework.security.userdetails.UserDetails;
|
||||
import org.springframework.security.userdetails.UserDetailsService;
|
||||
import org.springframework.security.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.util.StringSplitUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Processes a HTTP request's Digest authorization headers, putting the result into the
|
||||
* <code>SecurityContextHolder</code>.<p>For a detailed background on what this filter is designed to process,
|
||||
* refer to <a href="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617</a> (which superseded RFC 2069, although this
|
||||
* filter support clients that implement either RFC 2617 or RFC 2069).</p>
|
||||
* <p>This filter can be used to provide Digest authentication services to both remoting protocol clients (such as
|
||||
* Hessian and SOAP) as well as standard user agents (such as Internet Explorer and FireFox).</p>
|
||||
* <p>This Digest implementation has been designed to avoid needing to store session state between invocations.
|
||||
* <code>SecurityContextHolder</code>.
|
||||
* <p>
|
||||
* For a detailed background on what this filter is designed to process, refer to
|
||||
* <a href="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617</a> (which superseded RFC 2069, although this
|
||||
* filter support clients that implement either RFC 2617 or RFC 2069).
|
||||
* <p>
|
||||
* This filter can be used to provide Digest authentication services to both remoting protocol clients (such as
|
||||
* Hessian and SOAP) as well as standard user agents (such as Internet Explorer and FireFox).
|
||||
* <p>
|
||||
* This Digest implementation has been designed to avoid needing to store session state between invocations.
|
||||
* All session management information is stored in the "nonce" that is sent to the client by the {@link
|
||||
* DigestProcessingFilterEntryPoint}.</p>
|
||||
* <P>If authentication is successful, the resulting {@link org.springframework.security.Authentication Authentication}
|
||||
* object will be placed into the <code>SecurityContextHolder</code>.</p>
|
||||
* <p>If authentication fails, an {@link org.springframework.security.ui.AuthenticationEntryPoint AuthenticationEntryPoint}
|
||||
* DigestProcessingFilterEntryPoint}.
|
||||
* <p>
|
||||
* If authentication is successful, the resulting {@link org.springframework.security.Authentication Authentication}
|
||||
* object will be placed into the <code>SecurityContextHolder</code>.
|
||||
* <p>
|
||||
* If authentication fails, an {@link org.springframework.security.ui.AuthenticationEntryPoint AuthenticationEntryPoint}
|
||||
* implementation is called. This must always be {@link DigestProcessingFilterEntryPoint}, which will prompt the user
|
||||
* to authenticate again via Digest authentication.</p>
|
||||
* <p>Note there are limitations to Digest authentication, although it is a more comprehensive and secure solution
|
||||
* to authenticate again via Digest authentication.
|
||||
* <p>
|
||||
* Note there are limitations to Digest authentication, although it is a more comprehensive and secure solution
|
||||
* than Basic authentication. Please see RFC 2617 section 4 for a full discussion on the advantages of Digest
|
||||
* authentication over Basic authentication, including commentary on the limitations that it still imposes.</p>
|
||||
* authentication over Basic authentication, including commentary on the limitations that it still imposes.
|
||||
*/
|
||||
public class DigestProcessingFilter implements Filter, InitializingBean, MessageSourceAware {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
@ -108,13 +104,6 @@ public class DigestProcessingFilter implements Filter, InitializingBean, Message
|
|||
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
if (!(request instanceof HttpServletRequest)) {
|
||||
throw new ServletException("Can only process HttpServletRequest");
|
||||
}
|
||||
|
||||
if (!(response instanceof HttpServletResponse)) {
|
||||
throw new ServletException("Can only process HttpServletResponse");
|
||||
}
|
||||
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
|
||||
|
@ -128,7 +117,7 @@ public class DigestProcessingFilter implements Filter, InitializingBean, Message
|
|||
String section212response = header.substring(7);
|
||||
|
||||
String[] headerEntries = StringSplitUtils.splitIgnoringQuotes(section212response, ',');
|
||||
Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", "\"");
|
||||
Map<String,String> headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", "\"");
|
||||
|
||||
String username = (String) headerMap.get("username");
|
||||
String realm = (String) headerMap.get("realm");
|
||||
|
|
|
@ -216,8 +216,8 @@ public class DigestProcessingFilterTests {
|
|||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
public void testNonBase64EncodedNonceReturnsForbidden()
|
||||
throws Exception {
|
||||
@Test
|
||||
public void testNonBase64EncodedNonceReturnsForbidden() throws Exception {
|
||||
String nonce = "NOT_BASE_64_ENCODED";
|
||||
|
||||
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
|
||||
|
@ -232,8 +232,8 @@ public class DigestProcessingFilterTests {
|
|||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
public void testNonceWithIncorrectSignatureForNumericFieldReturnsForbidden()
|
||||
throws Exception {
|
||||
@Test
|
||||
public void testNonceWithIncorrectSignatureForNumericFieldReturnsForbidden() throws Exception {
|
||||
String nonce = new String(Base64.encodeBase64("123456:incorrectStringPassword".getBytes()));
|
||||
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
|
||||
REQUEST_URI, QOP, nonce, NC, CNONCE);
|
||||
|
@ -247,8 +247,8 @@ public class DigestProcessingFilterTests {
|
|||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
public void testNonceWithNonNumericFirstElementReturnsForbidden()
|
||||
throws Exception {
|
||||
@Test
|
||||
public void testNonceWithNonNumericFirstElementReturnsForbidden() throws Exception {
|
||||
String nonce = new String(Base64.encodeBase64("hello:ignoredSecondElement".getBytes()));
|
||||
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
|
||||
REQUEST_URI, QOP, nonce, NC, CNONCE);
|
||||
|
@ -262,8 +262,8 @@ public class DigestProcessingFilterTests {
|
|||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
public void testNonceWithoutTwoColonSeparatedElementsReturnsForbidden()
|
||||
throws Exception {
|
||||
@Test
|
||||
public void testNonceWithoutTwoColonSeparatedElementsReturnsForbidden() throws Exception {
|
||||
String nonce = new String(Base64.encodeBase64("a base 64 string without a colon".getBytes()));
|
||||
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
|
||||
REQUEST_URI, QOP, nonce, NC, CNONCE);
|
||||
|
@ -277,8 +277,8 @@ public class DigestProcessingFilterTests {
|
|||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
public void testNormalOperationWhenPasswordIsAlreadyEncoded()
|
||||
throws Exception {
|
||||
@Test
|
||||
public void testNormalOperationWhenPasswordIsAlreadyEncoded() throws Exception {
|
||||
String encodedPassword = DigestProcessingFilter.encodePasswordInA1Format(USERNAME, REALM, PASSWORD);
|
||||
String responseDigest = DigestProcessingFilter.generateDigest(true, USERNAME, REALM, encodedPassword, "GET",
|
||||
REQUEST_URI, QOP, NONCE, NC, CNONCE);
|
||||
|
@ -293,8 +293,8 @@ public class DigestProcessingFilterTests {
|
|||
((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername());
|
||||
}
|
||||
|
||||
public void testNormalOperationWhenPasswordNotAlreadyEncoded()
|
||||
throws Exception {
|
||||
@Test
|
||||
public void testNormalOperationWhenPasswordNotAlreadyEncoded() throws Exception {
|
||||
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
|
||||
REQUEST_URI, QOP, NONCE, NC, CNONCE);
|
||||
|
||||
|
@ -308,7 +308,8 @@ public class DigestProcessingFilterTests {
|
|||
((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername());
|
||||
}
|
||||
|
||||
public void testOtherAuthorizationSchemeIsIgnored()
|
||||
@Test
|
||||
public void otherAuthorizationSchemeIsIgnored()
|
||||
throws Exception {
|
||||
request.addHeader("Authorization", "SOME_OTHER_AUTHENTICATION_SCHEME");
|
||||
|
||||
|
@ -317,32 +318,22 @@ public class DigestProcessingFilterTests {
|
|||
assertNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
public void testStartupDetectsMissingAuthenticationEntryPoint()
|
||||
throws Exception {
|
||||
try {
|
||||
DigestProcessingFilter filter = new DigestProcessingFilter();
|
||||
filter.setUserDetailsService(new InMemoryDaoImpl());
|
||||
filter.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("A DigestProcessingFilterEntryPoint is required", expected.getMessage());
|
||||
}
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void startupDetectsMissingAuthenticationEntryPoint() throws Exception {
|
||||
DigestProcessingFilter filter = new DigestProcessingFilter();
|
||||
filter.setUserDetailsService(new InMemoryDaoImpl());
|
||||
filter.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public void testStartupDetectsMissingUserDetailsService()
|
||||
throws Exception {
|
||||
try {
|
||||
DigestProcessingFilter filter = new DigestProcessingFilter();
|
||||
filter.setAuthenticationEntryPoint(new DigestProcessingFilterEntryPoint());
|
||||
filter.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("A UserDetailsService is required", expected.getMessage());
|
||||
}
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void startupDetectsMissingUserDetailsService() throws Exception {
|
||||
DigestProcessingFilter filter = new DigestProcessingFilter();
|
||||
filter.setAuthenticationEntryPoint(new DigestProcessingFilterEntryPoint());
|
||||
filter.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public void testSuccessLoginThenFailureLoginResultsInSessionLosingToken()
|
||||
throws Exception {
|
||||
@Test
|
||||
public void successfulLoginThenFailedLoginResultsInSessionLosingToken() throws Exception {
|
||||
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
|
||||
REQUEST_URI, QOP, NONCE, NC, CNONCE);
|
||||
|
||||
|
@ -368,8 +359,8 @@ public class DigestProcessingFilterTests {
|
|||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
public void testWrongCnonceBasedOnDigestReturnsForbidden()
|
||||
throws Exception {
|
||||
@Test
|
||||
public void wrongCnonceBasedOnDigestReturnsForbidden() throws Exception {
|
||||
String cnonce = "NOT_SAME_AS_USED_FOR_DIGEST_COMPUTATION";
|
||||
|
||||
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
|
||||
|
@ -384,7 +375,8 @@ public class DigestProcessingFilterTests {
|
|||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
public void testWrongDigestReturnsForbidden() throws Exception {
|
||||
@Test
|
||||
public void wrongDigestReturnsForbidden() throws Exception {
|
||||
String password = "WRONG_PASSWORD";
|
||||
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, password, "GET",
|
||||
REQUEST_URI, QOP, NONCE, NC, CNONCE);
|
||||
|
@ -398,7 +390,8 @@ public class DigestProcessingFilterTests {
|
|||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
public void testWrongRealmReturnsForbidden() throws Exception {
|
||||
@Test
|
||||
public void wrongRealmReturnsForbidden() throws Exception {
|
||||
String realm = "WRONG_REALM";
|
||||
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, realm, PASSWORD, "GET",
|
||||
REQUEST_URI, QOP, NONCE, NC, CNONCE);
|
||||
|
@ -412,7 +405,8 @@ public class DigestProcessingFilterTests {
|
|||
assertEquals(401, response.getStatus());
|
||||
}
|
||||
|
||||
public void testWrongUsernameReturnsForbidden() throws Exception {
|
||||
@Test
|
||||
public void wrongUsernameReturnsForbidden() throws Exception {
|
||||
String responseDigest = DigestProcessingFilter.generateDigest(false, "NOT_A_KNOWN_USER", REALM, PASSWORD,
|
||||
"GET", REQUEST_URI, QOP, NONCE, NC, CNONCE);
|
||||
|
||||
|
|
Loading…
Reference in New Issue