Spring-security:记住我只有一次令牌工作

gui*_*dev 8 spring-security remember-me

春天安全问题我遇到了一个非常奇怪的问题.

记住我的令牌似乎仅持续一次自动登录,之后,它停止工作.

1.登录后:

在此输入图像描述

2.然后,我手动删除JSESSIONID cookie并重新加载页面

在此输入图像描述

3.我再次删除JSESSIONID cookie并再次重新加载页面.

现在,我退出了!

在控制台中,我得到了这个:

SEVERE [http-nio-8080-exec-10] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [dispatcher] in context with path [] threw exception
 org.springframework.security.web.authentication.rememberme.CookieTheftException: Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack.
Run Code Online (Sandbox Code Playgroud)

我读到这可能是浏览器同时发出多个请求的结果,我检查了(禁用所有资源,只留下纯HTML,但无济于事)

在此输入图像描述

这是我的配置

@EnableWebSecurity
public class Security extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Autowired
    DataSource dataSource;

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

        http.authorizeRequests().antMatchers("/assets/**").permitAll();
        http.authorizeRequests().anyRequest().authenticated();

        http.formLogin().permitAll();    
        http.rememberMe().tokenRepository(persistentTokenRepository()).userDetailsService(customUserDetailsService);

        http.logout().permitAll();
    }

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

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(customUserDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(11);
    }
}
Run Code Online (Sandbox Code Playgroud)

Usa*_*jad 1

从配置中提取数据源对我有用,尝试一下

@Autowired
JpaConfiguration jpaConfig;

@Bean(name = "persistentTokenRepository")
public PersistentTokenRepository persistentTokenRepository() {
    JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
    tokenRepository.setDataSource(jpaConfig.dataSource());
    return tokenRepository;
}
Run Code Online (Sandbox Code Playgroud)

或者您也可以尝试提高令牌有效性

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

        http.authorizeRequests().antMatchers("/assets/**").permitAll();
        http.authorizeRequests().anyRequest().authenticated();

        http.formLogin().permitAll();    
        http.rememberMe().tokenRepository(persistentTokenRepository()).userDetailsService(customUserDetailsService)
            .tokenValiditySeconds(1209600);

        http.logout().permitAll();
    }
Run Code Online (Sandbox Code Playgroud)