天天看点

Spring Security RememberMe的令牌持久化JdbcTokenRepositoryImpl的工作原理

JdbcTokenRepositoryImpl

简介

SpringSecurity的令牌持久化接口PersistentTokenRepository的一个实现类JdbcTokenRepositoryImpl。

作用

将原本存于内存的session存入数据库。

session持久化的优点

  1. 避免使用内存session,一旦用户量大了,内存极有可能爆掉。
  2. 避免使用内存session,重启后需要重新登录。

使用方法

数据库配置步骤省略。

1. 配置存储器

Spring Security RememberMe的令牌持久化JdbcTokenRepositoryImpl的工作原理

2. 配置SpringSecurity过滤器链

Spring Security RememberMe的令牌持久化JdbcTokenRepositoryImpl的工作原理

3. 登录开启记住我

Spring Security RememberMe的令牌持久化JdbcTokenRepositoryImpl的工作原理

4、 使用测试

  1. 登录成功关闭浏览器。
  2. 再重新打开网页,发现自动登录成功。

工作原理

1. JdbcTokenRepositoryImpl类简介

基于Jdbc对数据库进行操作,自身携带固定的表结构。

Spring Security RememberMe的令牌持久化JdbcTokenRepositoryImpl的工作原理

2. JdbcTokenRepositoryImpl创建的表结构

Spring Security RememberMe的令牌持久化JdbcTokenRepositoryImpl的工作原理

3. 将series和token使用base64进行加密,放入前端的remember-me的cookie中

Spring Security RememberMe的令牌持久化JdbcTokenRepositoryImpl的工作原理
Spring Security RememberMe的令牌持久化JdbcTokenRepositoryImpl的工作原理

3. remember-me cookie的简介

SpringSecurity默认对认证用的创建的cookie是“阅后即焚”策略。而JdbcTokenRepositoryImpl会在用户浏览器创建一个浏览器关闭不会消失的cookie(有一定时间限制),在进行登录时通过remember-me cookie作为SpringSecurity默认cookie不存在时的一个备用认证策略。

4. 源码分析

  1. RememberMeAuthenticationFilter检测到默认cookie不存在时,调用AbstractRememberMeServices的autoLogin。
  2. AbstractRememberMeServices获取用户传来的rememberMeCookie,对rememberMeCookie进行解码,获取其中的series和token字段。
  3. AbstractRememberMeServices调用PersistentTokenBasedRememberMeServices#processAutoLoginCookie对rememberMeCookie进行验证并解析用户数据。
  4. PersistentTokenBasedRememberMeServices拿到series和token到数据库比对,失败抛出CookieTheftException,并清除用户cookie、数据库中该用户的所有认证字段(意味着该账户密码泄露,所有登录成功的端都将登录失效,需要重新登录)。
    Spring Security RememberMe的令牌持久化JdbcTokenRepositoryImpl的工作原理
  5. 若比对成功则series不变,token刷新。将token重写写入数据库、重设rememberMeCookie。生成用户认证信息,用户登录成功。

JdbcTokenRepositoryImpl在实际场景下的作用

  1. 每次使用rememberMe进行登录,rememberMe中的token部分都会刷新。
  2. 如果rememberMeCookie泄露给黑客,正常用户在自动登录一次后会重新生成token,rememberMeCookie也得以更新。由于rememberMeCookie的更新便会使得黑客手中的rememberMeCookie失效(old)。
  3. 此时,黑客若再使用rememberMeCookie进行登录,在SpringSecurity取出rememberMeCookie中的series和token与数据库中的最新的series和token比对时发现不匹配,将判定为用户rememberMeCookie泄露。
  4. 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
);

           
Spring Security RememberMe的令牌持久化JdbcTokenRepositoryImpl的工作原理
username

与用户表关联的标识符。

series

勾选记住我+用户密码登录时创建,之后除非删除否则不会改变,主要作用是作为该表id,用于查token。

token

使用rememberMeCookie自动登录时会刷新,和series组合生成rememberMeCookie。每次使用“记住我”自动登录时刷新,用来防止rememberMeCookie泄露。

last_used

使用rememberMeCookie自动登录时会刷新,可以用来判断认证信息是否超过期限。