JdbcTokenRepositoryImpl
简介
SpringSecurity的令牌持久化接口PersistentTokenRepository的一个实现类JdbcTokenRepositoryImpl。
作用
将原本存于内存的session存入数据库。
session持久化的优点
- 避免使用内存session,一旦用户量大了,内存极有可能爆掉。
- 避免使用内存session,重启后需要重新登录。
使用方法
数据库配置步骤省略。
1. 配置存储器

2. 配置SpringSecurity过滤器链
3. 登录开启记住我
4、 使用测试
- 登录成功关闭浏览器。
- 再重新打开网页,发现自动登录成功。
工作原理
1. JdbcTokenRepositoryImpl类简介
基于Jdbc对数据库进行操作,自身携带固定的表结构。
2. JdbcTokenRepositoryImpl创建的表结构
3. 将series和token使用base64进行加密,放入前端的remember-me的cookie中
3. remember-me cookie的简介
SpringSecurity默认对认证用的创建的cookie是“阅后即焚”策略。而JdbcTokenRepositoryImpl会在用户浏览器创建一个浏览器关闭不会消失的cookie(有一定时间限制),在进行登录时通过remember-me cookie作为SpringSecurity默认cookie不存在时的一个备用认证策略。
4. 源码分析
- RememberMeAuthenticationFilter检测到默认cookie不存在时,调用AbstractRememberMeServices的autoLogin。
- AbstractRememberMeServices获取用户传来的rememberMeCookie,对rememberMeCookie进行解码,获取其中的series和token字段。
- AbstractRememberMeServices调用PersistentTokenBasedRememberMeServices#processAutoLoginCookie对rememberMeCookie进行验证并解析用户数据。
- PersistentTokenBasedRememberMeServices拿到series和token到数据库比对,失败抛出CookieTheftException,并清除用户cookie、数据库中该用户的所有认证字段(意味着该账户密码泄露,所有登录成功的端都将登录失效,需要重新登录)。
Spring Security RememberMe的令牌持久化JdbcTokenRepositoryImpl的工作原理 - 若比对成功则series不变,token刷新。将token重写写入数据库、重设rememberMeCookie。生成用户认证信息,用户登录成功。
JdbcTokenRepositoryImpl在实际场景下的作用
- 每次使用rememberMe进行登录,rememberMe中的token部分都会刷新。
- 如果rememberMeCookie泄露给黑客,正常用户在自动登录一次后会重新生成token,rememberMeCookie也得以更新。由于rememberMeCookie的更新便会使得黑客手中的rememberMeCookie失效(old)。
- 此时,黑客若再使用rememberMeCookie进行登录,在SpringSecurity取出rememberMeCookie中的series和token与数据库中的最新的series和token比对时发现不匹配,将判定为用户rememberMeCookie泄露。
- rememberMeCookie泄露,将触发删除所有该用户的授权cookie与数据库persistent_logins表中该用户的所有与该用户名关联的数据行,最终导致所有的用户都将需要使用密码重新登录。
综上所述
我们可以总结persistent_logins各个字段的主要作用:
create table persistent_logins
(
username varchar(64) not null,
series varchar(64) not null
primary key,
token varchar(64) not null,
last_used timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP
);
username
与用户表关联的标识符。
series
勾选记住我+用户密码登录时创建,之后除非删除否则不会改变,主要作用是作为该表id,用于查token。
token
使用rememberMeCookie自动登录时会刷新,和series组合生成rememberMeCookie。每次使用“记住我”自动登录时刷新,用来防止rememberMeCookie泄露。
last_used
使用rememberMeCookie自动登录时会刷新,可以用来判断认证信息是否超过期限。