Acegi Security: Custom Authentication
Posted on 31 May 2007
I’ve been using Acegi Security in several projects with good results. It’s powerful and flexible! Sadly, sometimes, developers have problems when they want to customize it. The code is the best documentation, so, I recommend them to read the code and javadocs. Well, this time I’ll show you how to customize the authentication. I assume a good knowledge of Spring Framework and basic knowledge of Acegi Security.
1: <bean id="authenticationProcessingFilter" 2: class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"> 3: <property name="authenticationManager" ref="authenticationManager"/> 4: <property name="authenticationFailureUrl" value="/login.htm?login_error=1"/> 5: <property name="defaultTargetUrl" value="/foobar.htm"/> 6: <property name="filterProcessesUrl" value="/j_acegi_security_check"/> 7: </bean>
You usually define a bean like authenticationProcessingFilter and add it to a chain in the FilterChainProxy bean. With this configuration, you attempt to authenticate when a request to /j_acegi_security_check has been made, delegating the authentication to the authenticationManager bean. If everything is OK, the user is redirected to /foobar.htm otherwise to /login.htm?login_error=1
Most of the time, you will be happy with this configuration but what happens if you need to do some additional validations before authentication. You have to extend AuthenticationProcessingFilter
01: package net.modlost.framework.security; 02: 03: import java.io.IOException; 04: 05: import javax.servlet.http.HttpServletRequest; 06: import javax.servlet.http.HttpServletResponse; 07: 08: import org.acegisecurity.AuthenticationException; 09: import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter; 10: 11: /** 12: * @author Abner Ballardo Urco 13: * 14: */ 15: public class CustomAuthenticationProcessingFilter extends 16: AuthenticationProcessingFilter { 17: 18: @Override 19: protected void onPreAuthentication(HttpServletRequest request, 20: HttpServletResponse response) throws AuthenticationException, 21: IOException { 22: 23: if (! validAuthenticationRequest(request,response)) { 24: throw new FooBarAuthenticationException(); 25: } 26: 27: } 28: 29: private boolean validAuthenticationRequest(HttpServletRequest request, 30: HttpServletResponse response) { 31: return false; 32: } 33: 34: }
Acegi provides a handily method: onPreAuthentication, you just need to override it, do your additional validations and throw an exception when the validation failed. This exception could extend AuthenticationException or IOException.
01: package net.modlost.framework.security; 02: 03: import org.acegisecurity.AuthenticationException; 04: 05: /** 06: * @author Abner Ballardo Urco 07: * 08: */ 09: public class FooBarAuthenticationException extends AuthenticationException { 10: 11: public FooBarAuthenticationException() { 12: super("FooBar Authentication Exception"); 13: } 14: 15: }
If onPreAuthentication doesn’t throw an exception, the normal authentication process continues. This isn’t the end of the story, what happens if you need to show different views according to the exception?. This step is a peace of cake!
01: <bean id="authenticationProcessingFilter" 02: class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"> 03: <property name="authenticationManager" ref="authenticationManager"/> 04: <property name="authenticationFailureUrl" value="/login.htm?login_error=1"/> 05: <property name="defaultTargetUrl" value="/foobar.htm"/> 06: <property name="filterProcessesUrl" value="/j_acegi_security_check"/> 07: <property name="exceptionMappings"> 08: <props> 09: <prop key="net.modlost.framework.security.FooBarAuthenticationException">/foobarError.jsp</prop> 10: </props> 11: </property> 12: </bean>
Defining the property exceptionMappings in authenticationProcessingFilter you can add all the exceptions (from Acegi and yours) and the urls to redirect to. If the exception is not found in exceptionMappings the default authenticationFailureUrl will be used.
No responses yet. You could be the first!







