java - Spring 安全 : CookieTheftException with PersistentTokenBasedRememberMeServices

标签 java spring spring-boot spring-security

我有一个带有 spring-boot 2.0.1 并受 spring-security 保护的 Web 应用程序。我为 Remember-Me 使用 PersistentTokenRepository 并将 token 存储在 MySQL 数据库中。

在服务器日志文件中,我看到很多带有 CookieTheftException 的堆栈跟踪。数量如此之多,以至于我很难相信实际的 Cookie 被盗,而是假设存在某种错误配置。从添加一些分析代码来看,似乎只有移动浏览器受到影响。

Servlet.service() for servlet [dispatcherServlet] in context with path [/r] threw exception
  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.4.RELEASE.jar!/:5.0.4.RELEASE]

手动测试无法重现这一点。删除 session cookie,但保留记住我的 Cookie 并向受限 URL 发出请求会导致正常的经过身份验证的 session 。

以下是我的安全配置的相关部分:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {
    @Configuration
    public static class SecurityConfiguration extends WebSecurityConfigurerAdapter {

        @Autowired
        private RememberMeServices rememberMeServices;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .rememberMe()
                    .key(rememberMeKey)
                    .rememberMeServices(rememberMeServices);
            ;
        }
    }

    /**
     * Key for RememberMeServices and RememberMeAuthenticationProvider.
     */
    private static final String rememberMeKey = "...";

    @Bean
    public RememberMeServices rememberMeServices(UserDetailsService userDetailsService, PersistentTokenRepository persistentTokenRepository) {
        PersistentTokenBasedRememberMeServices rememberMeServices = new AnalyzingPersistentTokenBasedRememberMeServices(
                rememberMeKey, userDetailsService, persistentTokenRepository);
        rememberMeServices.setTokenValiditySeconds((int) Duration.of(366L, ChronoUnit.DAYS).toSeconds());
        return rememberMeServices;
    }

    @Bean
    public PersistentTokenRepository persistentTokenRepository(JdbcTemplate jdbcTemplate) {
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setJdbcTemplate(jdbcTemplate);
        return tokenRepository;
    }
}

AnalyzingPersistentTokenBasedRememberMeServices 是一个 PersistentTokenBasedRememberMeServices,在 processAutoLoginCookie 中有一些额外的日志记录。

另一个特点是,我使用自定义的 AuthenticationProvider,并仅为 RememberMe 提供 UserDetailsS​​ervice。但如上所述,手动测试工作得很好。不过,用户报告说他们经常注销( session 超时为 24 小时)。

有没有人遇到过这样的事情并有解决方案?我是否遗漏了一些关键配置?

最佳答案

PersistentTokenBasedRememberMeServices 不适合具有并发请求的应用程序,这些请求可能会发送相同的 token 系列。

查看这些近五年 Unresolved 错误报告:

https://github.com/spring-projects/spring-security/issues/2648

https://github.com/spring-projects/spring-security/issues/3079

使用 TokenBasedRememberMeServices 没有这些问题。

关于java - Spring 安全 : CookieTheftException with PersistentTokenBasedRememberMeServices,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50223161/

相关文章:

java - 在 Sublime Text 3 中构建文件以调用 JUnit5 测试

java - eclipse - hibernate : No suitable driver found for jdbc:mysql://localhost:3306/hibernatedb

java - Spring Security 注解 @EnableWebSecurity 在 Spring MVC 项目中不起作用

java - 如何为spring data elasticsearch添加排序

java - 无法将 Spring Boot Admin Server 2 和 Spring Boot Admin Client 2 与 Spring Boot 2 集成在单个应用程序中

java - 将 org.apache.poi.ss.usermodel.Cell 的 Cellstyle 设置为 boolean 值

java - 尝试调用从另一个类调用另一个方法的方法时出现 StackOverflowError

java - Spring/JPA 多线程死锁

java - 防止spring-data-rest解析json

spring - Thymeleaf:动态构建变量名