Spring Security(5)

打印 上一主题 下一主题

主题 855|帖子 855|积分 2565

您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~
 
经常上网的人都应该有这样的体验:很多网站或者APP只需要第一次登录时输入用户名和密码之后,后面很长一段时间内就不需要再次输入密码了。这确实是一个非常好的体验,不然每次都让人输用户名和密码就太麻烦了。
Spring Security也提供了这样的功能,也就是Remember-Me(记住我)。
要实现这个功能也异常简单:只需要稍稍修改一下WebSecurityConfiguration即可:
  1. // 控制逻辑
  2. @Override
  3. protected void configure(HttpSecurity http) throws Exception {
  4.     http.authorizeRequests()
  5.             .anyRequest().authenticated()
  6.             // 设置自定义认证成功、失败及登出处理器
  7.             .and().formLogin().loginPage("/login")
  8.             .successHandler(successHandler).failureHandler(failureHandler).permitAll()
  9.             .and().logout().logoutUrl("/logout").deleteCookies("JSESSIONID")
  10.             .logoutSuccessHandler(logoutSuccessHandler).permitAll()
  11.             // 配置无权访问的自定义处理器
  12.             .and().exceptionHandling().accessDeniedHandler(accessDeniedHandler)
  13.             // 记住我
  14.             .and().rememberMe()
  15.             .and()
  16.             .cors().and().csrf().disable();
  17. }
复制代码
 
 
在postman的参数中增加remember-me参数,并设为true再访问就行了:

 
 
 
 
结果也很清楚:

 
 
 
 
 
虽然用cookie实现记住我很方便,但是如果涉及到敏感信息的话,cookie太过简单满足不了需求。所以,Spring Security提供了另外一种实现机制:保存到数据库中。也就是自动登录时,用cookie中的加密串到数据库中验证,如果通过,自动登录才算成功。使用这种方式实现remember-me很简单,只需要在WebSecurityConfiguration中增加一段代码就行了:
  1. // 控制逻辑
  2. @Override
  3. protected void configure(HttpSecurity http) throws Exception {
  4.     http.authorizeRequests()
  5.             .anyRequest().authenticated()
  6.             // 设置自定义认证成功、失败及登出处理器
  7.             .and().formLogin().loginPage("/login")
  8.             .successHandler(successHandler).failureHandler(failureHandler).permitAll()
  9.             .and().logout().logoutUrl("/logout").deleteCookies("JSESSIONID")
  10.             .logoutSuccessHandler(logoutSuccessHandler).permitAll()
  11.             // 配置无权访问的自定义处理器
  12.             .and().exceptionHandling().accessDeniedHandler(accessDeniedHandler)
  13.             // 记住我
  14.             .and().rememberMe()
  15.             // 数据库保存,这种方式在关闭服务之后仍然有效
  16.             .tokenRepository(persistentTokenRepository())
  17.             // 默认的失效时间会从用户最后一次操作开始计算过期时间,过期时间最小值就是60秒,
  18.             // 如果设置的值小于60秒,也会被更改为60秒
  19.             .tokenValiditySeconds(30 * 24 * 60 * 60)
  20.             .and()
  21.             .cors().and().csrf().disable();
  22. }
复制代码
 
 
因为需要在数据库中保存,那么自然就需要创建相应的数据库表:

 
 
 
同样,在WebSecurityConfiguration中再加入如下代码(需要注意的是,datasource是不能够通过连接池得到的,这里连接池注入的是javax.sql.DataSource):
  1. // 如果使用hikariCP这里就无法注入DataSource
  2. @Autowired
  3. private DataSource dataSource;
  4. // MySQL方式实现记住我
  5. @Bean
  6. public PersistentTokenRepository persistentTokenRepository() {
  7.     // mysql方式
  8.     JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
  9.     // 需要给JdbcTokenRepositoryImpl注入一个数据源,实现CRUD
  10.     tokenRepository.setDataSource(dataSource);
  11.     return tokenRepository;
  12. }
复制代码
 
 
这样就可以了,然后运行postman进行测试。
可以看到,由于是60秒失效,因此在第一次访问60秒后,再调用同样的接口时,名称为remember-me的cookie消失了。数据库的persistent_logins表中也多了一条用户访问记录。
失效规律:
1、过期时间的最小值是60秒,如果设置的值小于60秒,也会被更改为60秒;
2、默认的失效时间会从用户最后一次操作开始计算过期时间。
 
MySQL虽然方便,但是一般MySQL是用来保存主要业务数据的,这种技术性的数据最好不要和业务混在一起。所以,下一次就来说说怎么用NoSQL实现记住我。
 
 
 
 
感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

八卦阵

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表