From 9649003d57453b4df118fb268d0aad642f11e8dd Mon Sep 17 00:00:00 2001 From: Ray Krueger Date: Mon, 28 Mar 2005 17:42:21 +0000 Subject: [PATCH] AbstractProcessingFilter no longer uses a set*FailureUrl approach for every exception, it now uses a properties object that maps authenticationExceptions to failure urls --- .../ui/AbstractProcessingFilter.java | 169 +++++------------- .../ui/AbstractProcessingFilterTests.java | 54 +++--- doc/xdocs/changes.xml | 1 + 3 files changed, 64 insertions(+), 160 deletions(-) diff --git a/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java index bacb49aedc..17f785f7b3 100644 --- a/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java @@ -18,15 +18,9 @@ package net.sf.acegisecurity.ui; import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.AuthenticationException; import net.sf.acegisecurity.AuthenticationManager; -import net.sf.acegisecurity.AuthenticationServiceException; -import net.sf.acegisecurity.BadCredentialsException; -import net.sf.acegisecurity.CredentialsExpiredException; -import net.sf.acegisecurity.DisabledException; -import net.sf.acegisecurity.LockedException; import net.sf.acegisecurity.context.ContextHolder; import net.sf.acegisecurity.context.security.SecureContext; import net.sf.acegisecurity.context.security.SecureContextUtils; -import net.sf.acegisecurity.providers.cas.ProxyUntrustedException; import net.sf.acegisecurity.ui.rememberme.NullRememberMeServices; import net.sf.acegisecurity.ui.rememberme.RememberMeServices; @@ -39,12 +33,9 @@ import org.springframework.util.Assert; import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import java.util.Properties; + +import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -95,9 +86,33 @@ import javax.servlet.http.HttpServletResponse; * * * + *

+ * To configure this filter to redirect to specfic pages as the result of + * specific {@link AuthenticationException}s you can do the following. + * Configure the exceptionMappings property in your application + * xml. This property is a java.util.Properties object that maps a + * fully-qualified exception class name to a redirection url target.
+ * For example:
+ * <property name="exceptionMappings">
+ *   <props>
+ *     <prop> key="net.sf.acegisecurity.BadCredentialsException">/bad_credentials.jsp</prop>
+ *   </props>
+ * </property>
+ *

+ * The example above would redirect all {@link + * net.sf.acegisecurity.BadCredentialsException}s thrown, to a page in the + * web-application called /bad_credentials.jsp. + *

+ * + *

+ * Any {@link AuthenticationException} thrown that cannot be matched in the + * exceptionMappings will be redirected to the + * authenticationFailureUrl + *

* * @author Ben Alex * @author colin sampaleanu + * @author Ray Krueger * @version $Id$ */ public abstract class AbstractProcessingFilter implements Filter, @@ -111,42 +126,12 @@ public abstract class AbstractProcessingFilter implements Filter, //~ Instance fields ======================================================== private AuthenticationManager authenticationManager; + private Properties exceptionMappings = new Properties(); private RememberMeServices rememberMeServices = new NullRememberMeServices(); - /** - * Where to redirect the browser if authentication fails due to incorrect - * credentials - */ - private String authenticationCredentialCheckFailureUrl; - - /** - * Where to redirect the browser if authentication fails due to the users - * account being disabled - */ - private String authenticationDisabledFailureUrl; - /** Where to redirect the browser to if authentication fails */ private String authenticationFailureUrl; - /** - * Where to redirect the browser if authentication fails due to the users - * account being locked - */ - private String authenticationLockedFailureUrl; - - /** - * Where to redirect the browser if authentication fails due to the user's - * proxy being considered untrusted - */ - private String authenticationProxyUntrustedFailureUrl; - - /** - * Where to redirect the browser if authentication fails due to failure of - * the authentication service - */ - private String authenticationServiceFailureUrl; - private String credentialsExpiredFailureUrl; - /** * Where to redirect the browser to if authentication is successful but * ACEGI_SECURITY_TARGET_URL_KEY is null @@ -201,6 +186,14 @@ public abstract class AbstractProcessingFilter implements Filter, */ public abstract String getDefaultFilterProcessesUrl(); + public void setExceptionMappings(Properties exceptionMappings) { + this.exceptionMappings = exceptionMappings; + } + + public Properties getExceptionMappings() { + return new Properties(exceptionMappings); + } + public void setRememberMeServices(RememberMeServices rememberMeServices) { this.rememberMeServices = rememberMeServices; } @@ -222,24 +215,6 @@ public abstract class AbstractProcessingFilter implements Filter, public abstract Authentication attemptAuthentication( HttpServletRequest request) throws AuthenticationException; - public void setAuthenticationCredentialCheckFailureUrl( - String authenticationCredentialCheckFailureUrl) { - this.authenticationCredentialCheckFailureUrl = authenticationCredentialCheckFailureUrl; - } - - public String getAuthenticationCredentialCheckFailureUrl() { - return authenticationCredentialCheckFailureUrl; - } - - public void setAuthenticationDisabledFailureUrl( - String authenticationDisabledFailureUrl) { - this.authenticationDisabledFailureUrl = authenticationDisabledFailureUrl; - } - - public String getAuthenticationDisabledFailureUrl() { - return authenticationDisabledFailureUrl; - } - public void setAuthenticationFailureUrl(String authenticationFailureUrl) { this.authenticationFailureUrl = authenticationFailureUrl; } @@ -248,15 +223,6 @@ public abstract class AbstractProcessingFilter implements Filter, return authenticationFailureUrl; } - public void setAuthenticationLockedFailureUrl( - String authenticationLockedFailureUrl) { - this.authenticationLockedFailureUrl = authenticationLockedFailureUrl; - } - - public String getAuthenticationLockedFailureUrl() { - return authenticationLockedFailureUrl; - } - public void setAuthenticationManager( AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; @@ -266,33 +232,6 @@ public abstract class AbstractProcessingFilter implements Filter, return authenticationManager; } - public void setAuthenticationProxyUntrustedFailureUrl( - String authenticationProxyUntrustedFailureUrl) { - this.authenticationProxyUntrustedFailureUrl = authenticationProxyUntrustedFailureUrl; - } - - public String getAuthenticationProxyUntrustedFailureUrl() { - return authenticationProxyUntrustedFailureUrl; - } - - public void setAuthenticationServiceFailureUrl( - String authenticationServiceFailureUrl) { - this.authenticationServiceFailureUrl = authenticationServiceFailureUrl; - } - - public String getAuthenticationServiceFailureUrl() { - return authenticationServiceFailureUrl; - } - - public void setCredentialsExpiredFailureUrl( - String credentialsExpiredFailureUrl) { - this.credentialsExpiredFailureUrl = credentialsExpiredFailureUrl; - } - - public String getCredentialsExpiredFailureUrl() { - return credentialsExpiredFailureUrl; - } - public void setDefaultTargetUrl(String defaultTargetUrl) { this.defaultTargetUrl = defaultTargetUrl; } @@ -403,8 +342,10 @@ public abstract class AbstractProcessingFilter implements Filter, HttpServletResponse response) throws IOException {} /** + *

* Indicates whether this filter should attempt to process a login request * for the current invocation. + *

* *

* Subclasses may override for special requirements, such as Tapestry @@ -474,37 +415,9 @@ public abstract class AbstractProcessingFilter implements Filter, logger.debug("Updated ContextHolder to contain null Authentication"); } - String failureUrl = authenticationFailureUrl; - - if (failed instanceof AuthenticationServiceException - && (authenticationServiceFailureUrl != null)) { - failureUrl = authenticationServiceFailureUrl; - } - - if (failed instanceof BadCredentialsException - && (this.authenticationCredentialCheckFailureUrl != null)) { - failureUrl = authenticationCredentialCheckFailureUrl; - } - - if (failed instanceof DisabledException - && (authenticationDisabledFailureUrl != null)) { - failureUrl = authenticationDisabledFailureUrl; - } - - if (failed instanceof LockedException - && (authenticationLockedFailureUrl != null)) { - failureUrl = authenticationLockedFailureUrl; - } - - if (failed instanceof ProxyUntrustedException - && (authenticationProxyUntrustedFailureUrl != null)) { - failureUrl = authenticationProxyUntrustedFailureUrl; - } - - if (failed instanceof CredentialsExpiredException - && (credentialsExpiredFailureUrl != null)) { - failureUrl = credentialsExpiredFailureUrl; - } + String failureUrl = exceptionMappings.getProperty(failed.getClass() + .getName(), + authenticationFailureUrl); if (logger.isDebugEnabled()) { logger.debug("Authentication request failed: " + failed.toString()); diff --git a/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java index d34acf9224..4269171fa3 100644 --- a/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java @@ -17,15 +17,7 @@ package net.sf.acegisecurity.ui; import junit.framework.TestCase; -import net.sf.acegisecurity.Authentication; -import net.sf.acegisecurity.AuthenticationException; -import net.sf.acegisecurity.BadCredentialsException; -import net.sf.acegisecurity.GrantedAuthority; -import net.sf.acegisecurity.GrantedAuthorityImpl; -import net.sf.acegisecurity.MockAuthenticationManager; -import net.sf.acegisecurity.MockFilterConfig; -import net.sf.acegisecurity.MockHttpServletRequest; -import net.sf.acegisecurity.MockHttpServletResponse; +import net.sf.acegisecurity.*; import net.sf.acegisecurity.context.ContextHolder; import net.sf.acegisecurity.context.security.SecureContextImpl; import net.sf.acegisecurity.context.security.SecureContextUtils; @@ -34,12 +26,9 @@ import net.sf.acegisecurity.ui.rememberme.TokenBasedRememberMeServices; import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import java.util.Properties; + +import javax.servlet.*; import javax.servlet.http.HttpServletRequest; @@ -115,8 +104,26 @@ public class AbstractProcessingFilterTests extends TestCase { // Test executeFilterInContainerSimulator(config, filter, request, response, chain); + assertEquals("/myApp/failed.jsp", response.getRedirect()); assertNull(SecureContextUtils.getSecureContext().getAuthentication()); + + //Prepare again, this time using the exception mapping + filter = new MockAbstractProcessingFilter(new AccountExpiredException( + "You're account is expired")); + filter.setAuthenticationFailureUrl("/myApp/failed.jsp"); + + Properties exceptionMappings = filter.getExceptionMappings(); + exceptionMappings.setProperty(AccountExpiredException.class.getName(), + "/myApp/accountExpired.jsp"); + filter.setExceptionMappings(exceptionMappings); + + // Test + executeFilterInContainerSimulator(config, filter, request, response, + chain); + + assertEquals("/myApp/accountExpired.jsp", response.getRedirect()); + assertNull(SecureContextUtils.getSecureContext().getAuthentication()); } public void testFilterProcessesUrlVariationsRespected() @@ -168,25 +175,8 @@ public class AbstractProcessingFilterTests extends TestCase { filter.setFilterProcessesUrl("/p"); assertEquals("/p", filter.getFilterProcessesUrl()); - filter.setAuthenticationCredentialCheckFailureUrl("/foo"); - assertEquals("/foo", filter.getAuthenticationCredentialCheckFailureUrl()); - - filter.setAuthenticationDisabledFailureUrl("/dis"); - assertEquals("/dis", filter.getAuthenticationDisabledFailureUrl()); - filter.setAuthenticationFailureUrl("/fail"); assertEquals("/fail", filter.getAuthenticationFailureUrl()); - - filter.setAuthenticationLockedFailureUrl("/locked"); - assertEquals("/locked", filter.getAuthenticationLockedFailureUrl()); - - filter.setAuthenticationProxyUntrustedFailureUrl("/proxy"); - assertEquals("/proxy", - filter.getAuthenticationProxyUntrustedFailureUrl()); - - filter.setAuthenticationServiceFailureUrl("/serviceFailure"); - assertEquals("/serviceFailure", - filter.getAuthenticationServiceFailureUrl()); } public void testIgnoresAnyServletPathOtherThanFilterProcessesUrl() diff --git a/doc/xdocs/changes.xml b/doc/xdocs/changes.xml index 11d0a6297f..ef80cd4ba4 100644 --- a/doc/xdocs/changes.xml +++ b/doc/xdocs/changes.xml @@ -31,6 +31,7 @@ Handle null Authentication.getAuthorities() in AuthorizeTag Add credentialsExpiredFailureUrl getter/setter to AbstractProcessingFilter Update commons-codec dependency to 1.3 + AbstractProcessingFilter no longer has setters for failures, it uses the exceptionMappings property X509 (certificate-based) authentication support