Spring Security 6.x 系列(14)—— 会话管理之源码分析

一、前言

在上篇

Spring Security 6.x 系列(13)—— 会话管理之会话概念及常用配置

Spring Security 6.x 系列(14)—— 会话管理之会话固定攻击防护及Session共享

中了清晰了协议和会话的概念、对 Spring Security 中的常用会话配置进行了说明,并了解会话固定攻击防护和 Session 共享,今天我们着重对会话流程和部分源码进行分析。

二、保存会话

2.1 认证流程

以表单登录为例,提交登录后,进入 UsernamePasswordAuthenticationFilter 过滤器,认证流程如下:

在这里插入图片描述

其中源码如下:

在这里插入图片描述

如果身份验证成功,执行如下:

  • 在 ① 中 调用 SessionAuthenticationStrategy 进行会话策略处理,常用策略处理方式有:
    • 会话存储
    • 更改sessionid
    • 防范会话固定攻击
  • 在 ② 中调用 successfulAuthentication 方法:
    • SecurityContextHolder 上存储认证信息

    • SecurityContextRepository 上显式保存认证信息

    • RememberMeServices#loginSuccess 被调用。 如果未配置“记住我”,则为空操作。

    • ApplicationEventPublisher#InteractiveAuthenticationSuccessEvent 被调用发布认证成功事件。

    • AuthenticationSuccessHandler 被调用,重定向登录前URL。

我们先沿着 ① 分析会话策略。

2.2 会话策略

2.2.1 SessionAuthenticationStrategy

SessionAuthenticationStrategy 源码比较简单,就一个 onAuthentication 方法,当发生新的身份验证时,执行与 Http 会话相关的功能:

/*** Allows pluggable support for HttpSession-related behaviour when an authentication* occurs.* <p>* Typical use would be to make sure a session exists or to change the session Id to guard* against session-fixation attacks.** @author Luke Taylor* @since*/
public interface SessionAuthenticationStrategy {/*** Performs Http session-related functionality when a new authentication occurs.* @throws SessionAuthenticationException if it is decided that the authentication is* not allowed for the session. This will typically be because the user has too many* sessions open at once.*/void onAuthentication(Authentication authentication, HttpServletRequest request, HttpServletResponse response)throws SessionAuthenticationException;}

SessionAuthenticationStrategy 只是一个接口,这个接口有很多实现类:

在这里插入图片描述
我们在 DEBUG 看下在 UsernamePasswordAuthenticationFilter 过滤器,在认证成功时 SessionAuthenticationStrategy 的实现类,发现 CompositeSessionAuthenticationStrategy

在这里插入图片描述

2.2.2 CompositeSessionAuthenticationStrategy

直接看 CompositeSessionAuthenticationStrategyonAuthentication 方法实现:

/*** A {@link SessionAuthenticationStrategy} that accepts multiple* {@link SessionAuthenticationStrategy} implementations to delegate to. Each* {@link SessionAuthenticationStrategy} is invoked in turn. The invocations are short* circuited if any exception, (i.e. SessionAuthenticationException) is thrown.** <p>* Typical usage would include having the following delegates (in this order)* </p>** <ul>* <li>{@link ConcurrentSessionControlAuthenticationStrategy} - verifies that a user is* allowed to authenticate (i.e. they have not already logged into the application.</li>* <li>{@link SessionFixationProtectionStrategy} - If session fixation is desired,* {@link SessionFixationProtectionStrategy} should be after* {@link ConcurrentSessionControlAuthenticationStrategy} to prevent unnecessary* {@link HttpSession} creation if the* {@link ConcurrentSessionControlAuthenticationStrategy} rejects authentication.</li>* <li>{@link RegisterSessionAuthenticationStrategy} - It is important this is after* {@link SessionFixationProtectionStrategy} so that the correct session is registered.* </li>* </ul>** @author Rob Winch* @since 3.2*/
public class CompositeSessionAuthenticationStrategy implements SessionAuthenticationStrategy {private final Log logger = LogFactory.getLog(getClass());private final List<SessionAuthenticationStrategy> delegateStrategies;public CompositeSessionAuthenticationStrategy(List<SessionAuthenticationStrategy> delegateStrategies) {Assert.notEmpty(delegateStrategies, "delegateStrategies cannot be null or empty");for (SessionAuthenticationStrategy strategy : delegateStrategies) {Assert.notNull(strategy, () -> "delegateStrategies cannot contain null entires. Got " + delegateStrategies);}this.delegateStrategies = delegateStrategies;}@Overridepublic void onAuthentication(Authentication authentication, HttpServletRequest request,HttpServletResponse response) throws SessionAuthenticationException {int currentPosition = 0;int size = this.delegateStrategies.size();for (SessionAuthenticationStrategy delegate : this.delegateStrategies) {if (this.logger.isTraceEnabled()) {this.logger.trace(LogMessage.format("Preparing session with %s (%d/%d)",delegate.getClass().getSimpleName(), ++currentPosition, size));}delegate.onAuthentication(authentication, request, response);}}@Overridepublic String toString() {return getClass().getName() + " [delegateStrategies = " + this.delegateStrategies + "]";}}

是不是很熟悉?和我们在Spring Security 6.x 系列(11)—— Form表单认证和注销流程 中4.5 章节提到的注销处理器很相似。

CompositeSessionAuthenticationStrategy 中有一个 list 集合存储着 SessionAuthenticationStrategy 的实现类,然后遍历这个 list ,让它们去做真正的 session 处理操作。

现在的问题是,这个 delegateStrategies 中到底存储的是那些实现类呢?我们稍后进行解答。

2.2.3 SessionRegistry

可能有心急的小伙伴上来就想看 ConcurrentSessionControlAuthenticationStrategyChangeSessionIdAuthenticationStrategyRegisterSessionAuthenticationStrategyCsrfAuthenticationStrategy这四个strategy,但抱歉我们还缺点置条件,这个条件就是 SessionRegistry

搞明白 SessionRegistry 就知道了 Spring Security 是怎么保存 认证对象Session 的。

public interface SessionRegistry {/*** 获取所有的principal/List<Object> getAllPrincipals();/*** 获取principal的所有session/List<SessionInformation> getAllSessions(Object principal,boolean includeExpiredSessions);/*** 根据sessionId获取session的详细信息/SessionInformation getSessionInformation(String sessionId);/*** 根据sessionId刷新session信息/void refreshLastRequest(String sessionId);/*** 注册新的session信息/void registerNewSession(String sessionId, Object principal);/*** 根据sessionId删除session信息/void removeSessionInformation(String sessionId);
}

2.2.4 SessionRegistryImpl

Spring Security 通过SessionRegistryImpl来实现 Session 会话的统一管理,先看这个类的属性:

// <principal:Object,SessionIdSet>
private final ConcurrentMap<Object, Set<String>> principals;// <sessionId:Object,SessionInformation>
private final Map<String, SessionInformation> sessionIds;public SessionRegistryImpl() {
this.principals = new ConcurrentHashMap<>();
this.sessionIds = new ConcurrentHashMap<>();
}public SessionRegistryImpl(ConcurrentMap<Object, Set<String>> principals

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/322855.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕业设计——SpringBoot+vue仓库管理系统(附源码)

1&#xff0c;绪论 1.2&#xff0c;项目背景 随着电子计算机技术和信息网络技术的发明和应用&#xff0c;使着人类社会从工业经济时代向知识经济时代发展。在这个知识经济时代里&#xff0c;仓库管理系统将会成为企业生产以及运作不可缺少的管理工具。这个仓库管理系统是由&a…

展望2024: 中国AI算力能否引爆高性能计算和大模型训练的新革命?

★算力&#xff1b;算法&#xff1b;人工智能&#xff1b;高性能计算&#xff1b;高性能&#xff1b;高互联&#xff1b;生成式人工智能&#xff1b;StableDiffusion&#xff1b;ChatGPT&#xff1b;CoPilot&#xff1b;文本创建&#xff1b;图像生成&#xff1b;代码编写&…

就绪探针存活探针钩子

存活探针 livenessprobe 杀死容器&#xff0c;重启。 就绪探针 readinessProbe pod的状态是running ready状态是notready 容器不可以提供正常的业务访问&#xff0c;就绪探针不会重启容器 tcpSocket只是监听荣亲上的业务端口能否正常通信。8081没有&#xff0c;8080还在&am…

crontab 创建定时任务

1、创建crontab任务 crontab -ecrontab内容 */59 * * * * sh /home/restartAllSlave.sh >> /home/my-restartAllSlave.log 2>&12、创建执行脚本&#xff08;restartAllSlave.sh&#xff09; docker重启如下&#xff1a; docker restart slave_zllrp_gb_1 slav…

MessageBox:拓宽业务边界,HubSpot与WhatsApp的完美融合

在当今竞争激烈的商业环境中&#xff0c;企业必须迎合客户的多元化需求&#xff0c;通过创新的数字化工具实现全球化经营。今天运营坛将深度剖析MessageBox在连接HubSpot与WhatsApp上的独特价值&#xff0c;它在拓宽社交媒体界限、提升客户关系和实现国际化目标方面起着关键作用…

EasyRecovery2024操作安全、价格便宜的电脑数据恢复软件

EasyRecovery是一款操作安全、价格便宜、用户自主操作的非破坏性的只读应用程序&#xff0c;它不会往源驱上写任何东西&#xff0c;也不会对源驱做任何改变。它支持从各种各样的存储介质恢复删除或者丢失的文件&#xff0c;其支持的媒体介质包括&#xff1a;硬盘驱动器、光驱、…

迅为RK3588开发板编译 Buildroot单独编译图形化界面

编译 Buildroot Buildroot 是一款集成的编译集合包&#xff0c;解决了以前交叉编译麻烦的问题&#xff0c;本小节将介绍buildroot 镜像的编译流程&#xff0c;分为单独编译和完整全自动编译。 1 单独编译 1.1 图形化界面 本小节单独编译镜像的顺序如下所示&#xff1a; 单…

基于ssm的订餐管理系统论文

基于JSP的订餐管理系统的设计与实现 摘要 当下&#xff0c;正处于信息化的时代&#xff0c;许多行业顺应时代的变化&#xff0c;结合使用计算机技术向数字化、信息化建设迈进。传统的订餐信息管理模式&#xff0c;采用人工登记的方式保存相关数据&#xff0c;这种以人力为主的…

富文本BraftEditor引起的bug

1、BraftEditor踩坑1 #基于之前写的一篇BraftEditor的使用# 1. 问题起源&#xff1a; 打开编辑弹窗--> 下面页面所示--> 当进行分类选择时候&#xff0c;就会报错&#xff0c;并且这个报错还不是一直都有&#xff0c;6次选择出现一次报错吧 2. 解决&#xff1a; 2.1 起…

智慧农庄电商小程序(商城系统)

文章目录 项目简介商城功能项目结构技术选型后端使用的技术前端使用的技术 程序体验 项目简介 基于当前流行技术组合的前后端分离商城系统&#xff1a; SpringBoot2JpaMybatisPlusSpringSecurityjwtredisVue的前后端分离的商城系统&#xff0c; 包含商城、拼团、砍价、商户管理…

基于ssm学生档案管理系统论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 JSP技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

开箱秘籍,一招鲜吃遍天的Object.prototype.toString.call

在前端开发中&#xff0c;精准的数据类型判断是每一位开发者都必不可少的技能。就像熟知的 typeof 操作符&#xff0c;但在面对复杂数据类型时&#xff0c;仍然存在着局限性。 本文将深入剖析各类数据类型判断方法&#xff0c;特别聚焦于 Object.prototype.toString.call 这一…