Search code examples
springspring-bootspring-securityremember-me

Spring Security Remember Me fails with CookieTheftException


My SecurityConfig class where I configure remember-me feature backed by userService and persistenceTokenRepository():

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers(
                    "/js/**",
                    "/css/**",
                    "/img/**",
                    "/webjars/**").permitAll()
            .anyRequest().authenticated()
    // ... and login, and logout
    .and()
        .rememberMe()
            .userDetailsService(userService)
            .tokenRepository(persistentTokenRepository());
}

@Bean
public PersistentTokenRepository persistentTokenRepository() {
    JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
    tokenRepository.setDataSource(dataSource);
    return tokenRepository;
}

Use case:

  1. A user opens Login page in his browser, authorizes himself with enabled "Remember Me" option.
  2. [Back-end] New remember-me token is generated, persisted in DB and sent to the user. Default expiration is 2 weeks.
  3. The user is redirected to Homepage.
  4. The user closes the browser to end the browsing session.
  5. The user starts the browser again and goes to the Home page again.

Expected result: [Back-end] No exceptions, the token in DB is matched with the remember-me cookie. [Front-end] The user is successfully authenticated and can proceed to homepage.
Actual result: [Back-end] CookieTheftException is thrown. The token is deleted from DB. [Front-end] User is redirected to Login page.

org.springframework.security.web.authentication.rememberme.CookieTheftException: Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack.
    at org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices.processAutoLoginCookie(PersistentTokenBasedRememberMeServices.java:119) ~[spring-security-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]

Solution

  • This question is already answered here: Spring Security Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack. "Remember Me" feature is explained in details in that answer, I recommend you to read it before applying the following solution.

    I'd like to share my solution for Java configuration. Split static resources security from webapp pages security:

    http
        .authorizeRequests()
        .antMatchers(
            "/js/**",
            "/css/**",
            "/img/**",
            "/webjars/**").permitAll();
    
    http
        .authorizeRequests()
        .anyRequest().authenticated()
        // ... and login, and logout
        .and()
        .rememberMe()
        .userDetailsService(userService)
        .tokenRepository(persistentTokenRepository());
    

    It's up to you whether you define these two configurations in a single configure(HttpSecurity http) method or split them into two @Configuration classes. If you choose the latter option, don't forget to put @Order(int) annotations on these configurations, otherwise, you get a conflict.