Spring Security实现两周内自动登录"记住我"功能

作者:字母哥博客 时间:2021-12-15 17:59:22 

Spring Security实现两周内自动登录"记住我"功能

本文是Spring Security系列中的一篇。在上一篇文章中,我们通过实现UserDetailsService和UserDetails接口,实现了动态的从数据库加载用户、角色、权限相关信息,从而实现了登录及授权相关的功能。这一节就在此基础上新增,登录过程中经常使用的“记住我”功能,也就是我们经常会在各种网站登陆时见到的"两周内免登录",“三天内免登录”的功能。该功能的作用就是:当我们登录成功之后,一定的周期内当我们再次访问该网站,不需要重新登录。

一、最简实践

其实实现这个功能非常简单,只需要我们在重写WebSecurityConfigurerAdapter 方法配置HttpSecurity 的时候增加rememberMe()方法。(下面代码中省略了大量的关于Spring Security登录验证的配置,在本号此前的文章中已经讲过)


@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
 @Override
 protected void configure(HttpSecurity http) throws Exception {
   http.rememberMe();  //实现记住我自动登录配置,核心的代码只有这一行
 }
}

然后在登录表单中加入一个checkbox勾选框,name属性的值目前必须是“remember-me”(个性化更改的方法后面会讲)。


<label><input type="checkbox" name="remember-me"/>自动登录</label>

就是这么简单,我们就实现了记住我功能,默认效果是:2周内免登录。

二、实现原理

很多朋友可能看了上面的实现过程心里都犯懵,这样就实现了?下面和大家说明一下这过程中间,都做了哪些事情。

  • 当我们登陆的时候,除了用户名、密码,我们还可以勾选remember-me。

  • 如果我们勾选了remember-me,当我们登录成功之后服务端会生成一个Cookie返回给浏览器,这个Cookie的名字默认是remember-me;值是一个token令牌。

  • 当我们在有效期内再次访问应用时,经过RememberMeAuthenticationFilter,读取Cookie中的token进行验证。验正通过不需要再次登录就可以进行应用访问。

这个token令牌是一个 MD5 hash字符串:包含username、expirationTime和passwod和一个预定义的key,并将他们经过MD5加密。可能有的朋友会问:这样安全么?如果cookie被劫持,一定是不安全的,别人拿到了这个字符串在有效期内就可以访问你的应用。这就和你的钥匙token被盗了,你家肯定不安全是一个道理。 但是不存在密码被破解为明文的可能性,MD5 hash是不可逆的。

Spring Security实现两周内自动登录"记住我"功能

RememberMeAuthenticationFilter在Spring Security过滤器链中处于整体偏后的位置,所以只有当各种传统的登录方式都无法完成验证的情况下,才走RememberMeAuthenticationFilter,这也是符合实际需求的。

三、个性化配置

在实际的开发过程中,我们还可以根据需求做一些个性化的设置,如下:


.rememberMe()
 .rememberMeParameter("remember-me-new")
 .rememberMeCookieName("remember-me-cookie")
 .tokenValiditySeconds(2 * 24 * 60 * 60);

tokenValiditySeconds用于设置token的有效期,即多长时间内可以免除重复登录,单位是秒。不修改配置情况下默认是2周。

通过rememberMeParameter设置from表单“自动登录”勾选框的参数名称。如果这里改了,from表单中checkbox的name属性要对应的更改。如果不设置默认是remember-me。

rememberMeCookieName设置了保存在浏览器端的cookie的名称,如果不设置默认也是remember-me。如下图中查看浏览器的cookie。

Spring Security实现两周内自动登录"记住我"功能

四、token数据库存储方式

上面我们讲的方式,就是最简单的实现“记住我-自动登录”功能的方式。这种方式的缺点在于:token与用户的对应关系是在内存中存储的,当我们重启应用之后所有的token都将消失,即:所有的用户必须重新登陆。为此,Spring Security还给我们提供了一种将token存储到数据库中的方式,重启应用也不受影响。

有的文章说使用数据库存储方式是因为这种方式更安全,笔者不这么认为。虽然数据库存储的token的确不再是用户名、密码MD5加密字符串了,而是一个随机序列号。但是一旦你的随机序列号cookie被劫持,效果是一样的。好比你家有把密码锁:你把钥匙丢了和你把密码丢了,危害性是一样的。

Spring Security实现两周内自动登录"记住我"功能

上图是token数据库存储方式的实现原理和验证过程,下面我们就来实现一下。首先,我们需要键一张数据库表persistent_logins:


CREATE TABLE `persistent_logins` (
`username` varchar(64) NOT NULL,
`series` varchar(64) NOT NULL,
`token` varchar(64) NOT NULL,
`last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

初始化一个PersistentTokenRepository类型的Spring bean,并将系统使用的DataSource注入到该bean中。(当然前提一定是你已经在Spring Boot的application.yml中配置好DataSource相关的连接属性,这里不再赘述)


@Autowired
private DataSource dataSource;
@Bean
public PersistentTokenRepository persistentTokenRepository(){
  JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
  tokenRepository.setDataSource(dataSource);
  return tokenRepository;
}

最后在Spring Security配置方法configure(HttpSecurity http)加上如下的个性化配置:


.rememberMe()
 .tokenRepository(persistentTokenRepository())

总结

以上所述是小编给大家介绍的Spring Security实现两周内自动登录"记住我"功能网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

来源:https://www.cnblogs.com/zimug/archive/2019/11/28/11949330.html

标签:Spring,Security,自动登录
0
投稿

猜你喜欢

  • 简单了解springboot的jar包部署步骤

    2021-07-02 14:22:48
  • Spring Security过滤器链体系的实例详解

    2023-08-25 03:24:15
  • Java类的初始化顺序知识点总结

    2021-09-23 23:19:26
  • Java如何在临界区中避免竞态条件

    2022-11-02 09:39:29
  • Spring Boot + Mybatis-Plus实现多数据源的方法

    2023-11-13 15:01:46
  • 详解java封装实现Excel建表读写操作

    2023-12-24 11:17:20
  • Java实现Web应用中的定时任务(实例讲解)

    2022-08-12 23:40:02
  • java程序代码与文本对比实用工具简介

    2023-07-18 22:57:05
  • C#中using指令的几种用法

    2022-01-25 01:35:25
  • JavaCV调用百度AI实现人脸检测方法详解

    2023-01-09 01:16:09
  • java基于JDBC连接Oracle 11g Release2实例分析

    2022-06-06 02:36:36
  • Java线程池submit阻塞获取结果的实现原理详解

    2021-08-29 03:55:45
  • 详解Maven安装教程及是否安装成功

    2021-07-14 00:00:21
  • Java 数据结构与算法系列精讲之环形链表

    2023-04-27 22:37:07
  • spring-boot-maven-plugin:打包时排除provided依赖问题

    2023-07-18 02:12:11
  • 浅谈Java(SpringBoot)基于zookeeper的分布式锁实现

    2023-11-16 08:14:56
  • Spring实现默认标签解析流程

    2021-07-29 10:07:55
  • Android开发之android_gps定位服务简单实现

    2023-07-31 20:02:25
  • Spring MVC4.1服务器端推送实现过程解析

    2021-07-24 14:53:16
  • Gson之toJson和fromJson方法的具体使用

    2021-07-20 16:28:47
  • asp之家 软件编程 m.aspxhome.com