I have implemented 'Remember Me' functionality in my Spring MVC application using Spring Security 3.1
My security-context.xml looks like this :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<import resource="servlet-context.xml" />
<security:global-method-security secured-annotations="enabled" />
<security:http auto-config="true" authentication-manager-ref="am">
<!-- Restrict URLs based on role -->
<security:intercept-url pattern="/public/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
<!-- Override default login and logout pages -->
<security:form-login login-page="/public/login"
login-processing-url="/public/loginProcess"
default-target-url="/public/loginSuccess"
authentication-failure-url="/public/login?login_error=1"
always-use-default-target="true" />
<security:logout logout-url="/public/logout" logout-success-url="/public/login?logout=1" />
<security:remember-me services-alias="rmService" data-source-ref="dataSource"/>
<security:custom-filter position="LAST" ref="httpResponseAuthFilter" />
</security:http>
<security:authentication-manager id="am">
<security:authentication-provider >
<security:password-encoder ref="passwordEncoder" />
<security:jdbc-user-service data-source-ref="dataSource" />
</security:authentication-provider>
</security:authentication-manager>
<bean id="httpResponseAuthFilter"
class="mypackage.HttpResponseAuthenticationFilter" >
<property name="authenticationManager" ref="am"/>
<property name="rememberMeServices" ref="rmService"></property>
</bean>
</beans>
The Filter class is implemented like this :
public class HttpResponseAuthenticationFilter extends RememberMeAuthenticationFilter {
@Override
protected void onSuccessfulAuthentication(final HttpServletRequest request, final HttpServletResponse response,
final Authentication authResult) {
super.onSuccessfulAuthentication(request, response, authResult);
if (authResult != null) {
// process post authentication logic here..
}
}
}
Remember me functionality works fine using the above configuration but while running in eclipse debugger I found that HttpResponseAuthenticationFilter.onSuccessfulAuthentication() doesn't get invoked.
EDIT
After modifying my security-context.xmls and defining the remember-me service using standard Spring beans and referencing the service inside the configuration looks
<security:http auto-config="true" authentication-manager-ref="am">
<!-- Restrict URLs based on role -->
<security:intercept-url pattern="/public/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
<!-- Override default login and logout pages -->
<security:form-login login-page="/public/login"
login-processing-url="/public/loginProcess"
default-target-url="/public/loginSuccess"
authentication-failure-url="/public/login?login_error=1"
always-use-default-target="true" />
<security:remember-me services-ref="rememberMeService"/>
<security:logout logout-url="/public/logout" logout-success-url="/public/login?logout=1" />
<security:custom-filter position="LAST" ref="httpResponseAuthFilter" />
</security:http>
<security:authentication-manager id="am">
<security:authentication-provider >
<security:password-encoder ref="passwordEncoder" />
<security:jdbc-user-service data-source-ref="dataSource" />
</security:authentication-provider>
<security:authentication-provider ref="rememberMeAuthenticationProvider" />
</security:authentication-manager>
<bean id="rememberMeAuthenticationProvider" class=
"org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="riskAnalysis" />
</bean>
<bean id="httpResponseAuthFilter"
class="mypacakge.HttpResponseAuthenticationFilter" >
<property name="authenticationManager" ref="am"/>
<property name="rememberMeServices" ref="rememberMeService"></property>
</bean>
<bean id="rememberMeService"
class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="userDetailsService" />
<property name="key" value="riskAnalysis" />
</bean>
<bean id="userDetailsService"
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
Here is what I get in the logs :
*DEBUG: mypackage.HttpResponseAuthenticationFilter - SecurityContextHolder not populated with remember-me token, as it already contained: 'org.springframework.security.authentication.RememberMeAuthenticationToken@303f2184: Principal: org.springframework.security.core.userdetails.User@cb7ea6f6: Username: tarun4; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_USER'*
So it looks like authentication information is present in the session.
Thanks, Tarun