Dmytro Chyzhykov's Blog

Yet another programmer.

Spring Security Remember Me Token Customization

This article is about how to customize Spring Security Remember me attributes like:

  • SPRING_SECURITY_REMEMBER_ME_COOKIE cookie name
  • _spring_security_remember_me form field/parameter
  • token length

At first enable Remember Me feature by adding the <rememeber-me> tag in the <http> one.

1
2
3
4
5
6
<http ....>
    <!-- Remeber me -->
    <remember-me services-ref="rememberMeServices"/>

    <!-- The rest of your configuration is omitted-->
</http>

Then add a RememberMeServices implementation as the rememberMeServices bean.

1
2
3
4
5
6
7
8
9
10
11
12
13
<bean id="rememberMeServices"
      class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
    <constructor-arg value="myAppKey"/>
    <constructor-arg ref="userDetailsService"/>
    <constructor-arg ref="tokenRepository"/>
    <property name="cookieName" value="remember-me"/>
    <property name="tokenLength" value="32"/>
    <property name="parameter" value="remember-me-parameter"/>
</bean>

<bean id="tokenRepository"
      class="org.springframework.security.web.authentication.rememberme.InMemoryTokenRepositoryImpl">
</bean>

where:

  • key: A private key to prevent modification of the remember-me token
  • userDetailsService: A service which implements the UserDetailsService and loads user-specific data by username
  • tokenRepository: A Token Repository which holds all Remember Me Tokens, in this particular example it’s in-mememory implementation.
  • cookieName: Remember Me cookie name to be sent to a client
  • tokenLength: token length
  • parameter: Remember Me form field

The result Spring Security Context Configuration XML would look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<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"
       xmlns:context="http://www.springframework.org/schema/context"
       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
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.ffbit.bcrypt.security"/>

    <security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled"/>

    <security:http auto-config="true" use-expressions="true">
        <!-- Form login configuration -->
        <security:intercept-url pattern="/signin" access="permitAll"/>
        <security:form-login login-page="/signin"
                             login-processing-url="/security_check"
                             username-parameter="username"
                             password-parameter="password"
                             authentication-failure-url="/signin"/>

        <!-- Remeber me -->
        <security:remember-me services-ref="rememberMeServices"/>

        <!-- Fix problem redirecting to "/favicon.ico" -->
        <security:intercept-url pattern="/favicon.ico" access="permitAll"/>
        <!-- Static content -->
        <security:intercept-url pattern="/resources/**" access="permitAll"/>

        <security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
        <security:logout logout-url="/logout"/>
    </security:http>

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider user-service-ref="userDetailsService">
            <security:password-encoder ref="passwordEncoder"/>
        </security:authentication-provider>
    </security:authentication-manager>

    <bean id="passwordEncoder"
          class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

    <bean id="rememberMeServices"
          class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
        <constructor-arg value="myAppKey"/>
        <constructor-arg ref="userDetailsService"/>
        <constructor-arg ref="tokenRepository"/>
        <property name="cookieName" value="remember-me"/>
        <property name="tokenLength" value="32"/>
        <property name="parameter" value="remember-me-parameter"/>
    </bean>

    <bean id="tokenRepository"
          class="org.springframework.security.web.authentication.rememberme.InMemoryTokenRepositoryImpl">
    </bean>

</beans>

Read also:
- Improved Persistent Login Cookie Best Practice