Before I go on to describe what goes into it, thanks to the following. These links are a bit dated, but they did help me along.
Custom AuthenticationProcessingFilter for spring security to perform actions on login
An example of the security config for a custom auth filter (see last post)
Spring's documentation on adding own filters
Now, here we go. What is described below works for Spring Security 3.0.0.RELEASE.
1. We need to extend UsernamePasswordAuthenticationFilter
It used to be AuthenticationProcessingFilter, which is depricated.
In this example, we just write to the console. You would do something more important.
public class CustomUsernamePasswordAuthenticationFilter extends
UsernamePasswordAuthenticationFilter {
@Override
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response, Authentication authResult)
throws IOException, ServletException {
super.successfulAuthentication(request, response, authResult);
System.out.println("==successful login==");
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request,
HttpServletResponse response, AuthenticationException failed)
throws IOException, ServletException {
super.unsuccessfulAuthentication(request, response, failed);
System.out.println("==failed login==");
}
}
2. In spring security context, we will be overriding the form login filter FORM_LOGIN_FILTER.
This used to be AUTHENTICATION_PROCESSING_FILTER, which is not used now.
<http ...
<custom-filter position="FORM_LOGIN_FILTER" ref="customUsernamePasswordAuthenticationFilter">
Note: Since we are replacing the default FORM_LOGIN_FILTER, we should not use <form-login login-page... , as that will try to create the default filter and you would get an exception (that there are two filters defined at the same position).
3. Since we are using the custom FORM_LOGIN_FILTER, we need to set the following property on <http ..
<http auto-config="false"
4. Another thing to set at <http is entry-point-ref
Again, since we are altering the default behavior, we need to tell what is the entry point for the form login.
<http entry-point-ref="loginUrlAuthenticationEntryPoint"
And, correspondingly, define the loginUrlAuthenticationEntryPoint bean. Note that LoginUrlAuthenticationEntryPoint used to be AuthenticationProcessingFilterEntry which is depricated.
<beans:bean id="loginUrlAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.html">
</beans:bean>
5. Remember the filter 'customUsernamePasswordAuthenticationFilter ' we used in in step 2 and extended in step 1, we have to define it.
<beans:bean id="customUsernamePasswordAuthenticationFilter"
class="com.yourapp.web.security.CustomUsernamePasswordAuthenticationFilter" >
<beans:property name="authenticationManager" ref="authenticationManager">
<beans:property name="authenticationFailureHandler" ref="failureHandler">
<beans:property name="authenticationSuccessHandler" ref="successHandler">
</beans:bean>
<beans:bean id="successHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/login.html">
</beans:bean>
<beans:bean id="failureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login.html?login_error=true">
</beans:bean>
6. In the definition of 'customUsernamePasswordAuthenticationFilter' we are identifying the 'authenticationManager', so when you define your authentication manager provide an 'alias' for it:
<authentication-manager alias="authenticationManager">
...
</authentication-manager>
There you have it. Share and enjoy.