本文是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是不可逆的。

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。

四、token数据库存储方式

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

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

上图是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框架下实现两周内自动登录"记住我"功能的更多相关文章

  1. JS-两周内自动登录功能

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 在Spring Security框架下JWT的实现细节原理

    一.回顾JWT的授权及鉴权流程 在笔者的上一篇文章中,已经为大家介绍了JWT以及其结构及使用方法.其授权与鉴权流程浓缩为以下两句话 授权:使用可信用户信息(用户名密码.短信登录)换取带有签名的JWT令 ...

  3. Spring Security框架下Restful Token的验证方案

    项目使用Restful的规范,权限内容的访问,考虑使用Token验证的权限解决方案. 验证方案(简要概括): 首先,用户需要登陆,成功登陆后返回一个Token串: 然后用户访问有权限的内容时需要上传T ...

  4. 在Spring Boot框架下使用WebSocket实现聊天功能

    上一篇博客我们介绍了在Spring Boot框架下使用WebSocket实现消息推送,消息推送是一对多,服务器发消息发送给所有的浏览器,这次我们来看看如何使用WebSocket实现消息的一对一发送,模 ...

  5. Spring Security框架中踢人下线技术探索

    1.背景 在某次项目的开发中,使用到了Spring Security权限框架进行后端权限开发的权限校验,底层集成Spring Session组件,非常方便的集成Redis进行分布式Session的会话 ...

  6. Servlet课程0426(十一)Servlet Cookie实现两周内不用重复登录

    Welcome.java //登录界面 package com.tsinghua; import javax.servlet.http.*; import java.io.*; import java ...

  7. 在Spring Boot框架下使用WebSocket实现消息推送

    Spring Boot的学习持续进行中.前面两篇博客我们介绍了如何使用Spring Boot容器搭建Web项目(使用Spring Boot开发Web项目)以及怎样为我们的Project添加HTTPS的 ...

  8. Spring Boot 框架下使用MyBatis访问数据库之基于XML配置的方式

    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML ...

  9. Spring Security框架进阶、自定义登录

      1.Spring Security框架进阶 1.1 Spring Security简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安 ...

随机推荐

  1. 百万年薪python之路 -- MySQL数据库之 存储引擎

    MySQL之存储引擎 一. 存储引擎概述 定义: 存储引擎是mysql数据库独有的存储数据.为数据建立索引.更新数据.查询数据等技术的实现方法 ​ 首先声明一点: 存储引擎这个概念只有MySQL才有. ...

  2. Java接口统一样式返回模板

    Java接口统一样式返回模板 背景 在进行接口开发时,一般需要一个固定的返回样式,成功和失败的时候,都按照这种格式来进行统一的返回,这样,在与其他人进行接口之间的联调时不会显得很杂乱无章.而这种固定的 ...

  3. SpringBoot学习(二)探究Springboot启动机制

    引言: SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏.所以这次博主就跟你们一起探究一下SpringBoot的启动原 ...

  4. Method Not Allowed (GET): /boxuegos/index/ 错误

    1,Method Not Allowed (GET) 请求方法不被允许, 错误原因:我调用的是index这个方法,但是我上面定义了一个空的子路由,所以页面加载不了,控制台出现Method Not Al ...

  5. egg-mongoose --- nodejs

    项目 egg + mongoose 项目结构 配置 egg 安装模块 npm i egg-mongoose --save config/pulgin.js exports.mongoose = { e ...

  6. 前端技术之:通过plop生成Controller的方法与步骤

    # Controller的生成 开发者可以通过plop命令生成各种类型的控制器类(Normal.Restful.View), 以下是示例生成步骤. 1. 执行以下命令: plop controller ...

  7. git 命令归纳版

    1.克隆: 单纯的克隆名字: git clone [url] 自定义新建项目名称: git clone [url] [项目名字]   2.跟踪文件: git add [文件名]   3.添加忽略文件 ...

  8. 论文阅读 Prefetch-aware fingerprint cache management for data deduplication systems

    论文链接 https://link.springer.com/article/10.1007/s11704-017-7119-0 这篇论文试图解决的问题是在cache 环节之前,prefetch-ca ...

  9. 二叉查找树学习笔记(BST)

    我土了....终于开始看平衡树了,以前因为害怕一直不敢看数据结构...浑浑噩噩跟同学落了1—2个数据结构没看....果然,我是最弱的 二叉查找树,遵守每个点的左儿子小于点小于右儿子. 于是,BST能够 ...

  10. vue.config.js常用配置

    使用vue-cli3.0搭建项目比之前更简洁,没有了build和config文件夹. vue-cli3的一些服务配置都迁移到CLI Service里面了,对于一些基础配置和一些扩展配置需要在根目录新建 ...