AbstractProcessingFilter no longer uses a set*FailureUrl approach for every exception, it now uses a properties object that maps authenticationExceptions to failure urls
This commit is contained in:
parent
798ebb1a3d
commit
9649003d57
|
@ -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;
|
|||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* To configure this filter to redirect to specfic pages as the result of
|
||||
* specific {@link AuthenticationException}s you can do the following.
|
||||
* Configure the <code>exceptionMappings</code> 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.<br>
|
||||
* For example:<br>
|
||||
* <code> <property name="exceptionMappings"><br>
|
||||
* <props><br>
|
||||
* <prop> key="net.sf.acegisecurity.BadCredentialsException">/bad_credentials.jsp</prop><br>
|
||||
* </props><br>
|
||||
* </property><br>
|
||||
* </code><br>
|
||||
* The example above would redirect all {@link
|
||||
* net.sf.acegisecurity.BadCredentialsException}s thrown, to a page in the
|
||||
* web-application called /bad_credentials.jsp.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Any {@link AuthenticationException} thrown that cannot be matched in the
|
||||
* <code>exceptionMappings</code> will be redirected to the
|
||||
* <code>authenticationFailureUrl</code>
|
||||
* </p>
|
||||
*
|
||||
* @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 <code>null</code>
|
||||
|
@ -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 {}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Indicates whether this filter should attempt to process a login request
|
||||
* for the current invocation.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* 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());
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<action dev="benalex" type="fix">Handle null Authentication.getAuthorities() in AuthorizeTag</action>
|
||||
<action dev="benalex" type="update">Add credentialsExpiredFailureUrl getter/setter to AbstractProcessingFilter</action>
|
||||
<action dev="benalex" type="update">Update commons-codec dependency to 1.3</action>
|
||||
<action dev="raykrueger" type="update">AbstractProcessingFilter no longer has setters for failures, it uses the exceptionMappings property</action>
|
||||
</release>
|
||||
<release version="0.8.1" date="2005-03-22">
|
||||
<action dev="luke_t" type="add">X509 (certificate-based) authentication support</action>
|
||||
|
|
Loading…
Reference in New Issue