Announcement Announcement Module
Collapse
No announcement yet.
Spring 3.1 PersistentTokenBasedRememberMeServices and UsernamePasswordAuthentication Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring 3.1 PersistentTokenBasedRememberMeServices and UsernamePasswordAuthentication

    I'm using my own implementation of PersistentTokenBasedRememberMeServices and UsernamePasswordAuthenticationFilter and have a question regarding the remember me functionality when combined with a UsernamePasswordAuthenticationFilter.

    Based off of the configuration I have below, I would expect the successful authentication to return a remember-me cookie in the response headers, however this is not the case.

    The remember-me token appears to be generated and placed back onto the response, per the debug statements below. The problem seems to be that once the SavedRequestAwareAuthenticationSuccessHandlerredir ects to the defaultTargetURL, the remember-me header is gone. I'm running my test case using the TestRestCall class below, which basically authenticates against the j_spring_security_check. The JSessionID is present, but not the generated remember me token.

    I wrote my own implementation of the RememberMeServerices and UsernamePasswordAuthenticationFilter so that I could use headers instead of cookies.




    Server Output from Running TestRestCall:

    INFO: Server startup in 2490 ms
    obtainUsername: bob
    obtinaPassword: 12b141f35d58b8b3a46eea65e6ac179e
    rememberMeRequested parameter = _spring_security_remember_me value: true
    setCookie = MmY3bUVTY2ZNUjBrQk5tQWRKaVZnZz09OlVFc0VIMGVlcCtIbn IwbVN2VGx5WVE9PQ
    authToken name = bob
    authToken authorities = [ROLE_SUPERVISOR, ROLE_USER]
    authToken credentials = null
    authToken details = org.springframework.security.web.authentication.We bAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null
    authToken principal = org.springframework.security.core.userdetails.User @17db5: Username: bob; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_SUPERVISOR,ROLE_USER
    authToken isAuthenticated = true
    onLoginSuccess cookieValue = MmY3bUVTY2ZNUjBrQk5tQWRKaVZnZz09OlVFc0VIMGVlcCtIbn IwbVN2VGx5WVE9PQ
    PersistentTokenBasedRememberMeServices login SUCCESS
    extractRememberMeCookie cookieValue = null




    TokenBasedAuthenticationFilter.java
    Code:
    public class TokenBasedAuthenticationFilter extends UsernamePasswordAuthenticationFilter  {
    	
    	
    	@Override
    	protected String obtainPassword(HttpServletRequest request) {
    		System.out.println("obtinaPassword: " + request.getHeader(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_PASSWORD_KEY));
    		return request.getHeader(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_PASSWORD_KEY);
    	}
    
    	@Override
    	protected String obtainUsername(HttpServletRequest request) {
    		System.out.println("obtainUsername: " + request.getHeader(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY));		
    		return request.getHeader(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY);
    	}
    
    }

    RequestHeaderCheckingPersistentTokenBasedRememberM eServices.java
    Code:
    public class RequestHeaderCheckingPersistentTokenBasedRememberMeServices extends PersistentTokenBasedRememberMeServices{
    
    	
    	@Override
    	protected void onLoginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authToken) {
    		super.onLoginSuccess(request, response, authToken);
    		 System.out.println("authToken name = " + authToken.getName());
    		 System.out.println("authToken authorities = " + authToken.getAuthorities());
    		 System.out.println("authToken credentials = " + authToken.getCredentials());
    		 System.out.println("authToken details = " + authToken.getDetails());
    		 System.out.println("authToken principal = " + authToken.getPrincipal());
    		 System.out.println("authToken isAuthenticated = " + authToken.isAuthenticated());
    		 String cookieValue = response.getHeader(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
    		 System.out.println("onLoginSuccess cookieValue = " + cookieValue);
    		System.out.println("PersistentTokenBasedRememberMeServices login SUCCESS");
    	}
    	
    	
    		 @Override
    		 protected boolean rememberMeRequested(HttpServletRequest request, String parameter) {
    			 String value = request.getHeader(DEFAULT_PARAMETER);
    			 System.out.println("rememberMeRequested parameter = " + parameter + " value: " + value);
    			 return value != null && Boolean.parseBoolean(value)?Boolean.parseBoolean(value):super.rememberMeRequested(request, parameter);
    		 }
    		 
    		 @Override
    		 protected String extractRememberMeCookie(HttpServletRequest request) {
    			 String cookieValue = request.getHeader(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
    			 System.out.println("extractRememberMeCookie cookieValue = " + cookieValue);
    			 return cookieValue;
    		 }
    		 
    		 @Override
    		 protected void setCookie(String[] tokens, int maxAge, HttpServletRequest request, HttpServletResponse response) {
    			 String cookieValue = encodeCookie(tokens);
    			 System.out.println("setCookie = " + cookieValue);
    			 response.setHeader(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, cookieValue);
    		 }
    applicationContext.xml
    Code:
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:security="http://www.springframework.org/schema/security"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
              http://www.springframework.org/schema/security
              http://www.springframework.org/schema/security/spring-security-3.1.xsd">
    
    	<!-- Define which filters should be ran through for the given url pattern -->
    	<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    		<security:filter-chain-map path-type="ant">
    			<security:filter-chain pattern="/**" filters="authenticationProcessingFilter, rememberMeFilter" />
    		</security:filter-chain-map>
    	</bean>
    
    	<!-- The main filter for extracting credentials from the header - it extends 
    		UsernamePasswordAuthFilter -->
    	<bean id="authenticationProcessingFilter" class="com.test.TokenBasedAuthenticationFilter">
    
    		<!-- Defined -->
    		<property name="authenticationManager" ref="authenticationManager" />
    		<property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" />
    		<property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
    		<property name="rememberMeServices" ref="rememberMeServices" />
    		<property name="postOnly" value="false" />
    		<property name="allowSessionCreation" value="false" />
    
    	</bean>
    
    	<!-- The AuthenticationManager - a container for the various types of AuthenticationProviders. -->
    	<bean id="authenticationManager"
    		class="org.springframework.security.authentication.ProviderManager">
    		<property name="providers">
    			<list>
    				<ref bean="authenticationProvider" />
    				<ref bean="rememberMeAuthenticationProvider" />
    			</list>
    		</property>
    	</bean>
    
    	<!-- AuthenticationPRovider - dao To be used if you want to pull from the 
    		database / or a static definition in this example -->
    	<bean id="authenticationProvider"
    		class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    		<property name="userDetailsService" ref="userDetailsService" />
    	</bean>
    
    	<bean id="rememberMeServices"
    		class="com.test.RequestHeaderCheckingPersistentTokenBasedRememberMeServices">
    		<property name="key" value="thisIsTheKeyValueForHashCreation" />
    		<property name="userDetailsService" ref="userDetailsService" />
    		<property name="tokenRepository" ref="tokenRepository" />
    	</bean>
    
    	<!-- UserDetailsService (which is a dao interface for loading date specific 
    		to a user account In this example there is no DAO for retrieval, it's just 
    		a sample to play with. -->
    	<bean id="userDetailsService"
    		class="org.springframework.security.core.userdetails.memory.InMemoryDaoImpl">
    		<property name="userMap">
    			<value>bob=12b141f35d58b8b3a46eea65e6ac179e,ROLE_SUPERVISOR,ROLE_USER
    				sam=d1a5e26d0558c455d386085fad77d427,ROLE_USER
    			</value>
    		</property>
    	</bean>
    
    	<bean id="tokenRepository"
    		class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl">
    		<property name="createTableOnStartup" value="false" />
    		<property name="dataSource" ref="dataSource" />
    	</bean>
    
    	<bean id="rememberMeFilter"
    		class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
    		<property name="rememberMeServices" ref="rememberMeServices" />
    		<property name="authenticationManager" ref="authenticationManager" />
    	</bean>
    
    	<bean id="rememberMeAuthenticationProvider"
    		class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
    		<property name="key" value="thisIsTheKeyValueForHashCreation" />
    	</bean>
    
    	<!-- datasource to the database -->
    	<bean id="dataSource"
    		class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
    		<property name="driverClass" value="org.postgresql.Driver" />
    		<property name="url" value="jdbc:postgresql://localhost:5433/postgres" />
    		<property name="username" value="postgres" />
    		<property name="password" value="notUsed" />
    	</bean>
    
    	<!-- Send to this url if success (DashBoard) -->
    	<bean id="authenticationSuccessHandler"
    		class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
    		            <property name="defaultTargetUrl" value="/dashboard.jsp" />
    	</bean>
    
    	<!-- Send to this url if failed (LoginPage) -->
    	<bean id="authenticationFailureHandler"
    		class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
    		<property name="defaultFailureUrl">
    			<value>/exceptionFailure.jsp</value>
    		</property>
    	</bean>
    
    </beans>

  • #2
    I am too facing the same problem and When I restart my jetty server, persistent repository checks for the token in Database but not creating session to it

    Comment

    Working...
    X