加载中...
加载中...
SpringSecurity记住我看源码

SpringSecurity记住我看源码 原创

SpringSecurity记住我,分为两种方式

1、基于简单加密token的方法
2、持久化记住我两种实现:基于内存的;基于数据库的

上一篇,学会使用了两种记住我的代码实现,这一篇看看源码,更好的理解。

SpringSecurity记住我(两种方式)  

http://www.leixingke.com/article/detail/5D2WDCyp  

基于简单加密token的方法

流程:

1、 当用户首次发起认证请求,会被UsernamePasswordAuthenticationFilter拦截,然后身份认证;
2、 认证成功后,进入抽象类AbstractAuthenticationProcessingFilter中successfulAuthentication()
然后执行rememberMeServices.loginSuccess();
基于简单加密token的实现方式rememberMeServices的实现类是TokenBasedRememberMeServices

说明:RememberMeServices接口。该接口默认实现类是NullRememberMeServices,使用内存实现记住我,配置后调用另一个实现抽象类AbstractRememberMeServices,会由TokenBasedRememberMeServices去实现父类AbstractRememberMeServices中的抽象方法。
==================================================
3、 关闭浏览器,当发送第二次认证请求时,会被RememberMeAuthenticationFilter拦截。
它会判断cookie中所包含的关于Remember-Me的信息是否与系统一致,一致则返回一个RememberMeAuthenticationToken供RememberMeAuthenticationProvider处理,不一致则会删除客户端的Remember-Me cookie。TokenBasedRememberMeServices还实现了Spring Security的LogoutHandler接口,所以它可以在用户退出登录时立即清除Remember-Me cookie。

我们debug一下

1、先到了UsernamePasswordAuthenticationFilter

2  认证成功后,进入抽象类AbstractAuthenticationProcessingFiltersuccessfulAuthentication()

然后执行rememberMeServices.loginSuccess();
数据库实现方式rememberMeServices的实现类是TokenBasedRememberMeServices

 

说明:RememberMeServices接口。该接口默认实现类是NullRememberMeServices,使用数据库实现记住我,配置后调用另一个实现抽象类AbstractRememberMeServices,实现类为

TokenBasedRememberMeServices   


此时rememberMeServices实现类是TokenBasedRememberMeServices
进入loginSuccess()
进入类AbstractRememberMeServices
public abstract class AbstractRememberMeServices implements RememberMeServices, InitializingBean, LogoutHandler {}

可以看到如果requestname"remember-me"true时,才会调用下面的onLoginSuccess()方法。   

进入类TokenBasedRememberMeServices中的onLoginSuccess()
设置cookie,,,加密的

前端多了个cookie

1、 关闭浏览器,当发送第二次认证请求时,会被RememberMeAuthenticationFilter拦截。
基于简单加密token的方法,再次进入网页,获取认证的Authentication不为空,直接认证成功。



基于数据库的

流程:

1、 当用户首次发起认证请求,会被UsernamePasswordAuthenticationFilter拦截,然后身份认证;
2、 认证成功后,进入抽象类AbstractAuthenticationProcessingFilter中successfulAuthentication()
然后执行rememberMeServices.loginSuccess();
数据库实现方式rememberMeServices的实现类是PersistentTokenBasedRememberMeServices

说明:RememberMeServices接口。该接口默认实现类是NullRememberMeServices,使用数据库实现记住我,配置后调用另一个实现抽象类AbstractRememberMeServices,会由PersistentTokenBasedRememberMeServices去实现父类AbstractRememberMeServices中的抽象方法。

3、 在PersistentTokenBasedRememberMeServices中,有一个类PersistentTokenRepository,在onLoginSuccess()会生成一个Token,将token等信息添加的数据库中;并将这个Token写到cookie里面返回并浏览器。

说明:PersistentTokenRepository的默认实现类是InMemoryTokenRepositoryImpl,该默认实现类会将token保存到内存中。另一个实现类JdbcTokenRepositoryImpl,该类会将Token持久化到数据库中。
==================================================
4、 关闭浏览器,当发送第二次认证请求时,会被RememberMeAuthenticationFilter拦截。如果获取已经认证的Authentication为空,那么就会调用remeberMeServices的autoLogin自动登录方法。

5、 实现类PersistentTokenBasedRememberMeServices中,调用processAutoLoginCookie方法,获取用户相关信息。
方法功能:首先从cookie中获取token;然后根据token从数据库中获取信息,查不到就抛异常;查到就构建PersistentRememberMeToken,更新数据库中和cookie中的信息;最后返回UserDetails信息。
6、 如果认证成功,就向SecurityContext中添加Authentication返回,也就登录成功了。

我们debug一下

1、首先到了UsernamePasswordAuthenticationFilter


2  认证成功后,进入抽象类AbstractAuthenticationProcessingFiltersuccessfulAuthentication()

然后执行rememberMeServices.loginSuccess();
数据库实现方式rememberMeServices的实现类是PersistentTokenBasedRememberMeServices

 

说明:RememberMeServices接口。该接口默认实现类是NullRememberMeServices,使用数据库实现记住我,配置后调用另一个实现抽象类AbstractRememberMeServices,实现类为PersistentTokenBasedRememberMeServices 


进入loginSuccess()
调用AbstractRememberMeServices的loginSuccess()方法。
然后调用onLoginSuccess();


然后调用onLoginSuccess();
进入的是类PersistentTokenBasedRememberMeServices的onLoginSuccess();
方法onLoginSuccess();是核心,主要作用是:
1、将token等信息添加的数据库中;
2、将token添加到cookie中。


PersistentRememberMeToken

字段对应数据库中

复制收展Javapublic class PersistentRememberMeToken {
private final String username;
private final String series;
private final String tokenValue;
private final Date date;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
进入this.tokenRepository.createNewToken(persistentToken);
然后到了类JdbcTokenRepositoryImpl
public class JdbcTokenRepositoryImpl extends JdbcDaoSupport implements PersistentTokenRepository {}


创建表SQL,你可以手动创建这个表,也可以,配置
tokenRepository.setCreateTableOnStartup(true);

复制收展Javapublic 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)";
  • 1

然后,

浏览器就会多一个叫的cookie
数据库中就会多一条记录



当不注销,再次登录,
前端cookie会更新数据,数据库中会多一条记录,


当注销操作后,根据用户名username,这两条数据都会被删除。

=======================================================

当关闭浏览器,重新进入网页。会被RememberMeAuthenticationFilter拦截(其实每次请求都会拦截),

if (SecurityContextHolder.getContext().getAuthentication() == null) {}

如果获取已经认证的Authentication为空,那么就会调用remeberMeServices的autoLogin自动登录方法。


进入autoLogin()
到了抽象类AbstractRememberMeServices


进入类PersistentTokenBasedRememberMeServices
的processAutoLoginCookie()


首先从cookie中获取token;然后根据token从数据库中获取信息,查不到就抛异常;查到就构建PersistentRememberMeToken,更新数据库中和cookie中的信息;最后返回UserDetails信息。
如果认证成功,就向SecurityContext中添加Authentication


版本: spring-security:4.2.9.RELEASE


没有更多推荐了 [去首页]
image
文章
357
原创
284
转载
73
翻译
0
访问量
199056
喜欢
47
粉丝
6
码龄
5年
资源
0

文章目录

加载中...
0
0