Spring Security开启记住我功能
Spring Security 自带两种方式实现记住我功能(也就是自动登录)
1. 通过Cookie存储认证数据
这种方式十分简单,只要在 WebSecurityConfig 中的 configure() 方法添加一个 rememberMe() 即可:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.rememberMe();
}
当我们登陆时勾选自动登录时,会自动在 Cookie 中保存一个名为 remember-me 的cookie,默认有效期为2周,其值是一个加密字符串。但是这种方式问题也很明显,我们可以认为所有放在Cookie中的信息都是不安全的。所以Spring Security提供了第二种方式
2.数据库存储
在客户端的 Cookie中,仅保存一个无意义的加密串(与用户名、密码等敏感数据无关),然后在数据库中保存该加密串-用户信息的对应关系,自动登录时,用 Cookie 中的加密串,到数据库中验证,如果通过,自动登录才算通过。
当浏览器发起表单登录请求时,当通过 UsernamePasswordAuthenticationFilter 认证成功后,会经过 RememberMeService,在其中有个 TokenRepository,它会生成一个 token,首先将 token 写入到浏览器的 Cookie 中,然后将 token、认证成功的用户名写入到数据库中。
当浏览器下次请求时,会经过 RememberMeAuthenticationFilter,它会读取 Cookie 中的 token,交给 RememberMeService从数据库中查询记录。如果存在记录,会读取用户名并去调用 UserDetailsService,获取用户信息,并将用户信息放入Spring Security 中,实现自动登陆。
RememberMeAuthenticationFilter在整个过滤器链中是比较靠后的位置,也就是说在传统登录方式都无法登录的情况下才会使用自动登陆。
首先需要创建一张专门记录token数据的表。然后在 WebSecurityConfig 中注入 dataSource ,创建一个 PersistentTokenRepository 的Bean:
@Autowired
private DataSource dataSource;
@Bean
public PersistentTokenRepository persistentTokenRepository(){
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
// 如果token表不存在,使用下面语句可以初始化该表;若存在,请注释掉这条语句,否则会报错。
// tokenRepository.setCreateTableOnStartup(true);
return tokenRepository;
}
在 config() 中按如下所示配置自动登陆:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.rememberMe()
.tokenRepository(persistentTokenRepository())
// 有效时间:单位s
.tokenValiditySeconds(60)
.userDetailsService(userDetailsService);
}