javaspringspring-bootspring-securityspring-social

No Spring Security Remember me cookie created when logging in programmatically


Right after registration (sign up) I'm logging in my user programmatically via Spring Security:

public register(HttpServletRequest request, String user, String password) {
    ...
    request.login(user, password);
}

This works fine, but it doesn't create the remember-me cookie (although with interactive login the cookie is created fine).

Now I've read in this and this answer, that you have to wire in the implementation of RememberMeServices (I use PersistentTokenBasedRememberMeServices) and then call onLoginSuccess. I haven't been successful to autowire PersistentTokenBasedRememberMeServices.

How to make this work? Is this the right way? Why Spring Security doesn't offer a more convenient way?


P.S.: This is an excerpt from my configuration:

@Configuration
@EnableWebSecurity
public class WebSecConf extends WebSecurityConfigurerAdapter {

    ...

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .rememberMe()
                .tokenRepository(new MyPersistentTokenRepository())
                .rememberMeCookieName("rememberme")
                .tokenValiditySeconds(60 * 60 * 24) 
                .alwaysRemember(true)
                .useSecureCookie(true)
                .and()
            ....
       ...
    }
}

Solution

  • You didn't mention the Spring version. Below configuration will work with Spring 4 but you can modify it for other version. In your WebSecConf class autowire PersistentTokenRepository and UserDetailsService interfaces. Add Bean to get PersistentTokenBasedRememberMeServices instance.

    @Configuration
    @EnableWebSecurity
    public class WebSecConf extends WebSecurityConfigurerAdapter {
    
    @Autowired
    PersistentTokenRepository persistenceTokenRepository;
    @Autowired
    UserDetailsService userDetailsService;
        ...
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            http
                .rememberMe()
                    .tokenRepository(persistenceTokenRepository)
                    .rememberMeCookieName("rememberme")
                    .tokenValiditySeconds(60 * 60 * 24) 
                    .alwaysRemember(true)
                    .useSecureCookie(true)
                    .and()
                ....
           ...
        }
    
    @Bean
    public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() {
        PersistentTokenBasedRememberMeServices persistenceTokenBasedservice = new PersistentTokenBasedRememberMeServices("rememberme", userDetailsService, persistenceTokenRepository);
        persistenceTokenBasedservice.setAlwaysRemember(true);
        return persistenceTokenBasedservice;
      }
    }
    

    Now in your Controller or class where you are doing programmatic login, autowire PersistentTokenBasedRememberMeServices and add below code inside the method to invoke loginSuccess method.

    @Autowired
    PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices;
    
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null){
            persistentTokenBasedRememberMeServices.loginSuccess(request, response, auth);
        }