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);
}
posted @ 2020-09-29 10:55  大嘤熊  阅读(698)  评论(0编辑  收藏  举报