05 SpringSecurity-实现自动登录

文章配套代码:https://gitee.com/lookoutthebush/spring-security-demo

自动登录是将用户的登录信息保存在用户浏览器的cookie中,当用户下次访问时,自动实现校验 并建立登录态的一种机制。

Spring Security提供了两种非常好的令牌:

  • 用散列算法加密用户必要的登录信息并生成令牌。
  • 数据库等持久性数据存储机制用的持久化令牌。

散列算法在Spring Security中是通过加密几个关键信息实现的:

hashInfo = md5Hex(username + ":" + expirationTime + ":" + password + ":" + key)
rememberCookie = base64(username + ":" + expirationTime + ":" + hashInfo)

其中,expirationTime指本次自动登录的有效期,key为指定的一个散列盐值,用于防止令牌被修 改。通过这种方式生成cookie后,在下次登录时,SpringSecurity首先用Base64简单解码得到用户名、 过期时间和加密散列值;然后使用用户名得到密码;接着重新以该散列算法正向计算,并将计算结果与旧的加密散列值进行对比,从而确认该令牌是否有效。

一、散列加密方案

1、修改配置

 1、rememberMeCookieName设置的是生成的cookie的名字

2、rememberMeParameter设置的是前端登录是传参的名字,如下图,SpringSecurity会使用这个名字取前端的参数

 3、key是一个散列盐值,没有指定的时候是一个随机的UUID字符串,这样每次启动服务,或者部署多台机器都会导致自动登录使用的cookie失效。所以直接指定一个固定的。

4、userDetailService需要指定,用来查询用户信息进行对比

2.前端代码修改

            <div class="layui-form-item">
              <div class="layui-input-inline">
                <input type="checkbox" name="remember" title="记住我" >
              </div>
              <div class="layui-form-mid" style="float: right">
                <a href="#" class="wait" style="color: #777777">忘记密码</a>
              </div>
            </div>

具体可以查看开头的demo源码

3.启动服务

 登录后,查看cookie,会发现有了一个uc-token。

 之前每次重启项目都需要重新登录,现在重新启动服务,发现不需要登录了。

二、持久化令牌方案

持久化令牌方案在交互上与散列加密方案一致,都是在用户勾选Remember-me之后,将生成的令 牌发送到用户浏览器,并在用户下次访问系统时读取该令牌进行认证。不同的是,它采用了更加严谨 的安全性设计。

在持久化令牌方案中,最核心的是series和token两个值,它们都是用MD5散列过的随机字符串。 不同的是,series仅在用户使用密码重新登录时更新,而token会在每一个新的session中都重新生成。

这样设计有什么好处呢?

首先,解决了散列加密方案中一个令牌可以同时在多端登录的问题。持久化方案每个会话都会引发token的更 新,即每个token仅支持单实例登录。

其次,自动登录不会导致series变更,而每次自动登录都需要同时验证series和token两个值,当该 令牌还未使用过自动登录就被盗取时,系统会在非法用户验证通过后刷新 token 值,此时在合法用户的浏览器中,该token值已经失效。当合法用户使用自动登录时,由于该series对应的 token 不同,系统 可以推断该令牌可能已被盗用,从而做一些处理。例如,清理该用户的所有自动登录令牌,并通知该用户可能已被盗号等。

1.数据库表

SpringSecurity相关的代码逻辑已经实现了,对应的实体:

public class PersistentRememberMeToken {

	private final String username;

	private final String series;

	private final String tokenValue;

	private final Date date;

	public PersistentRememberMeToken(String username, String series, String tokenValue, Date date) {
		this.username = username;
		this.series = series;
		this.tokenValue = tokenValue;
		this.date = date;
	}

	public String getUsername() {
		return this.username;
	}

	public String getSeries() {
		return this.series;
	}

	public String getTokenValue() {
		return this.tokenValue;
	}

	public Date getDate() {
		return this.date;
	}

}

因此我们需要按照实体,创建一个数据库表:

数据库sql也有提供:

public class JdbcTokenRepositoryImpl extends JdbcDaoSupport implements PersistentTokenRepository {

	/** Default SQL for creating the database table to store the tokens */
	public static final String CREATE_TABLE_SQL = "create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, "
			+ "token varchar(64) not null, last_used timestamp not null)";

这里做了一些小改动,也可以按原样:

-- ---------------
-- 自动登录
-- ---------------
CREATE TABLE `persistent_logins` (
    `series` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '主键',
    `username` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '用户名',
    `token` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'token',
    `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后使用时间',
    PRIMARY KEY (`series`)
)ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT ='用户表';

表的主键是series,Spring Security可以通过series查询表中的其他信息。有了存储自动登录信息的表 之后,就可以继续配置Spring Security的Remember-me功能了。由于需要使用持久化令牌方案,所以指定tokenRepository。

2.修改配置类

仍然直接使用SpringSecurity提供的。

3.运行

输入账号密码登录成功后,查看数据库,会有一条数据产生。

 重启项目等都不需要再次登录。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实现Spring Security自动登录功能,你可以按照以下步骤进行操作: 1. 确保你已经将Spring Security添加到你的项目中,并配置好了基本的安全设置。 2. 创建一个实现了`UserDetailsService`接口的类,用于从数据库或其他数据源中加载用户信息。该接口中的`loadUserByUsername`方法根据用户名返回一个`UserDetails`对象,其中包含了用户的信息和权限。 3. 在Spring Security的配置文件中,使用`rememberMe()`方法启用自动登录功能,并配置相关参数。例如: ```java @Override protected void configure(HttpSecurity http) throws Exception { http .rememberMe() .key("yourSecretKey") // 设置一个密钥,用于生成和验证令牌 .userDetailsService(userDetailsService); // 设置刚才创建的UserDetailsService实现类 } ``` 4. 在用户登录成功后,使用`RememberMeServices`接口提供的方法生成一个持久化的令牌,并将其发送给客户端。 ```java @Autowired private RememberMeServices rememberMeServices; @PostMapping("/login") public String login(HttpServletRequest request, HttpServletResponse response) { // 处理用户登录逻辑 // 生成一个持久化的令牌并发送给客户端 rememberMeServices.loginSuccess(request, response, authentication); } ``` 5. 在应用程序启动时,配置一个`PersistentTokenRepository`实现类来管理持久化令牌的存储和检索。你可以选择将令牌存储在数据库中或其他持久化存储器中。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { // ... @Bean public PersistentTokenRepository persistentTokenRepository() { // 配置持久化令牌的存储和检索方式 // 例如,可以使用JdbcTokenRepositoryImpl将令牌存储在数据库中 JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl(); tokenRepository.setDataSource(dataSource); return tokenRepository; } } ``` 通过按照以上步骤进行配置,你就可以实现Spring Security自动登录功能了。当用户登录成功并选择“记住我”选项时,下次访问应用程序时就会自动使用持久化的令牌进行登录

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七号公园的忧伤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值