我的SecurityConfig
类,我在其中配置了由userService
和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;
}
用例:
- 用户在他的浏览器中打开登录页面,授权自己启用"记住我"选项。
- [后端] 新的"记住我"令牌生成,持久化在数据库中并发送给用户。默认有效期为 2 周。
- 用户被重定向到主页。
- 用户关闭浏览器以结束浏览会话。
- 用户再次启动浏览器并再次转到主页。
预期结果:[后端] 无异常,DB 中的令牌与"记住我"cookie 匹配。[前端]用户已成功通过身份验证,可以进入主页。
实际结果:抛出 [后端]CookieTheftException
。令牌将从数据库中删除。[前端]用户被重定向到登录页面。
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]
这个问题已经在这里得到了解答: 弹簧安全性 无效的记住我令牌(系列/令牌(不匹配。暗示以前的 cookie 盗窃攻击。"记住我"功能在该答案中有详细说明,我建议您在应用以下解决方案之前阅读它。
我想分享我的 Java 配置解决方案。将静态资源安全性与 Web 应用页面安全性拆分:
http
.authorizeRequests()
.antMatchers(
"/js/**",
"/css/**",
"/img/**",
"/webjars/**").permitAll();
http
.authorizeRequests()
.anyRequest().authenticated()
// ... and login, and logout
.and()
.rememberMe()
.userDetailsService(userService)
.tokenRepository(persistentTokenRepository());
是否在单个配置中定义这两种配置取决于您configure(HttpSecurity http)
方法或将它们拆分为两个@Configuration
类。如果选择后一个选项,请不要忘记在这些配置上放置@Order(int)
注释,否则会出现冲突。