SEC-180: BasicProcessingFilter should configurably ignore authentication failures.

This commit is contained in:
Ben Alex 2006-02-09 06:41:31 +00:00
parent e63b2ec9e6
commit b1dd784dee
2 changed files with 64 additions and 23 deletions

View File

@ -1,4 +1,4 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,8 +18,11 @@ package org.acegisecurity.ui.basicauth;
import org.acegisecurity.Authentication; import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationManager; import org.acegisecurity.AuthenticationManager;
import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.AuthenticationEntryPoint; import org.acegisecurity.ui.AuthenticationEntryPoint;
import org.acegisecurity.ui.WebAuthenticationDetails; import org.acegisecurity.ui.WebAuthenticationDetails;
@ -78,8 +81,9 @@ import javax.servlet.http.HttpServletResponse;
* </p> * </p>
* *
* <p> * <p>
* If authentication fails, an {@link AuthenticationEntryPoint} implementation * If authentication fails and <code>ignoreFailure</code> is <code>false</code>
* is called. Usually this should be {@link BasicProcessingFilterEntryPoint}, * (the default), an {@link AuthenticationEntryPoint} implementation is
* called. Usually this should be {@link BasicProcessingFilterEntryPoint},
* which will prompt the user to authenticate again via BASIC authentication. * which will prompt the user to authenticate again via BASIC authentication.
* </p> * </p>
* *
@ -110,27 +114,10 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
private AuthenticationEntryPoint authenticationEntryPoint; private AuthenticationEntryPoint authenticationEntryPoint;
private AuthenticationManager authenticationManager; private AuthenticationManager authenticationManager;
private boolean ignoreFailure = false;
//~ Methods ================================================================ //~ Methods ================================================================
public void setAuthenticationEntryPoint(
AuthenticationEntryPoint authenticationEntryPoint) {
this.authenticationEntryPoint = authenticationEntryPoint;
}
public AuthenticationEntryPoint getAuthenticationEntryPoint() {
return authenticationEntryPoint;
}
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
public AuthenticationManager getAuthenticationManager() {
return authenticationManager;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.notNull(this.authenticationManager, Assert.notNull(this.authenticationManager,
"An AuthenticationManager is required"); "An AuthenticationManager is required");
@ -196,7 +183,13 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
} }
SecurityContextHolder.getContext().setAuthentication(null); SecurityContextHolder.getContext().setAuthentication(null);
authenticationEntryPoint.commence(request, response, failed);
if (ignoreFailure) {
chain.doFilter(request, response);
} else {
authenticationEntryPoint.commence(request, response,
failed);
}
return; return;
} }
@ -214,5 +207,31 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
chain.doFilter(request, response); chain.doFilter(request, response);
} }
public AuthenticationEntryPoint getAuthenticationEntryPoint() {
return authenticationEntryPoint;
}
public AuthenticationManager getAuthenticationManager() {
return authenticationManager;
}
public void init(FilterConfig arg0) throws ServletException {} public void init(FilterConfig arg0) throws ServletException {}
public boolean isIgnoreFailure() {
return ignoreFailure;
}
public void setAuthenticationEntryPoint(
AuthenticationEntryPoint authenticationEntryPoint) {
this.authenticationEntryPoint = authenticationEntryPoint;
}
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
public void setIgnoreFailure(boolean ignoreFailure) {
this.ignoreFailure = ignoreFailure;
}
} }

View File

@ -285,7 +285,8 @@ public class BasicProcessingFilterTests extends MockObjectTestCase {
assertEquals(401, response.getStatus()); assertEquals(401, response.getStatus());
} }
public void testWrongPasswordReturnsForbidden() throws Exception { public void testWrongPasswordContinuesFilterChainIfIgnoreFailureIsTrue()
throws Exception {
// Setup our HTTP request // Setup our HTTP request
String token = "marissa:WRONG_PASSWORD"; String token = "marissa:WRONG_PASSWORD";
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
@ -294,6 +295,27 @@ public class BasicProcessingFilterTests extends MockObjectTestCase {
request.setServletPath("/some_file.html"); request.setServletPath("/some_file.html");
request.setSession(new MockHttpSession()); request.setSession(new MockHttpSession());
filter.setIgnoreFailure(true);
assertTrue(filter.isIgnoreFailure());
// Test - the filter chain will be invoked, as we've set ignoreFailure = true
MockHttpServletResponse response = executeFilterInContainerSimulator(filter,
request, true);
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
public void testWrongPasswordReturnsForbiddenIfIgnoreFailureIsFalse()
throws Exception {
// Setup our HTTP request
String token = "marissa:WRONG_PASSWORD";
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Authorization",
"Basic " + new String(Base64.encodeBase64(token.getBytes())));
request.setServletPath("/some_file.html");
request.setSession(new MockHttpSession());
assertFalse(filter.isIgnoreFailure());
// Test - the filter chain will not be invoked, as we get a 403 forbidden response // Test - the filter chain will not be invoked, as we get a 403 forbidden response
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, MockHttpServletResponse response = executeFilterInContainerSimulator(filter,
request, false); request, false);