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

时间:2018-04-12 19:19:34

标签: spring-security remember-me

我遇到了一个非常奇怪的弹簧安全问题。

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

1。登录后:

enter image description here

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

enter image description here

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.

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

enter image description here

这是我的配置

@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);
    }
}

1 个答案:

答案 0 :(得分:1)

从配置中提取dataSource对我有用,试试吧

@Autowired
JpaConfiguration jpaConfig;

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

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

 @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();
    }