SpringSecurity源码学习四:会话管理
目录
- 1. 什么是会话管理
- 2. springSecurity中的session管理怎么做的
- 3. springSecurity源码中的session管理
- 4. 代码示例
- 5. 源码
- 5.1 不同策略的含义
- 6. 集群模式session管理
- 7. 总结
1. 什么是会话管理
会话管理是指在Java应用程序中管理用户会话状态的过程。在Spring框架中,可以使用Spring Session来实现会话管理。Spring Session提供了一种机制,用于在不同的会话存储后端(例如内存、数据库、Redis等)中存储和管理会话数据。
通过使用Spring Session,您可以轻松地在Spring应用程序中管理会话。它提供了简单的API,用于创建、读取、更新和删除会话数据。您可以使用Spring的依赖注入机制将Spring Session集成到您的应用程序中,并根据需要配置会话存储后端。
会话管理在Web应用程序中尤为重要,因为它允许您跟踪用户的登录状态、存储用户特定的数据,并提供一种机制来管理会话的过期和超时。通过有效地管理会话,您可以提供更安全、可靠的用户体验,并确保应用程序的性能和可扩展性。
总而言之,会话管理是通过Spring Session在Java应用程序中管理用户会话状态的过程,它提供了一种机制来存储和管理会话数据,并确保应用程序的安全性和性能。
2. springSecurity中的session管理怎么做的
在Spring Security中,可以通过配置来管理会话。以下是在Spring Security中进行会话管理的一般步骤:
-
添加Spring Security依赖:在项目的构建文件(如pom.xml)中添加Spring Security的依赖项。
-
配置会话管理:在Spring Security的配置文件中,可以使用 sessionManagement() 方法来配置会话管理。例如,您可以设置会话超时时间、最大并发会话数等。
-
配置会话固定攻击防护:为了防止会话固定攻击,您可以使用 sessionFixation() 方法配置会话固定攻击防护策略。常见的防护策略包括更改会话ID、使用cookie作为会话ID等。
-
配置会话存储后端:您可以选择将会话数据存储在不同的后端,如内存、数据库、Redis等。根据您的需求,配置会话存储后端以存储和管理会话数据。
-
定义访问控制规则:使用Spring Security的访问控制规则,您可以定义哪些URL需要进行会话管理和访问控制。例如,您可以配置需要进行身份验证的URL,或者需要特定角色或权限才能访问的URL。
通过以上步骤,您可以在Spring Security中实现会话管理。具体的配置和实现方式可能会根据您的应用程序需求而有所不同。您可以参考Spring Security的官方文档和示例代码,以获得更详细的指导和示例。
3. springSecurity源码中的session管理
Security源码中会话管理的一般实现方式:
- SessionManagementConfigurer 接口:这是一个配置接口,用于配置会话管理的各个方面,如会话超时时间、最大并发会话数等。您可以使用 sessionManagement() 方法获取 SessionManagementConfigurer 实例,并通过调用其方法来配置会话管理。
- SessionFixationConfigurer 接口:这是一个配置接口,用于配置会话固定攻击防护策略。您可以使用 sessionFixation() 方法获取 SessionFixationConfigurer 实例,并通过调用其方法来配置会话固定攻击防护。
- SessionRegistry 接口:这是一个接口,用于管理并发会话。它提供了注册、注销和获取会话的方法,以及获取活动会话数等功能。 SessionRegistry 的默认实现是 SessionRegistryImpl 。
- ConcurrentSessionControlAuthenticationStrategy 类:这是一个会话控制策略类,用于限制并发会话数。它通过与 SessionRegistry 结合使用,检查当前用户的会话数并处理超出限制的情况。
- SessionAuthenticationStrategy 接口:这是一个接口,用于处理用户身份验证时的会话管理。它定义了在用户登录时如何处理会话,包括创建新会话、销毁旧会话等。
以上是Spring Security源码中会话管理的一般实现方式。具体的实现细节和类可能会根据不同版本的Spring Security而有所不同。如果您有兴趣深入了解Spring Security的会话管理实现,请参考Spring Security的源代码和文档。
4. 代码示例
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.sessionManagement().invalidSessionStrategy(invalidSessionStrategy()).maximumSessions(1) // 最大并发会话数.maxSessionsPreventsLogin(true) // 超出最大会话数时阻止登录.expiredSessionStrategy(expiredSessionStrategy()).and().and().logout().deleteCookies("JSESSIONID") // 在注销时删除会话ID的Cookie.invalidateHttpSession(true); // 注销时使会话失效}@Beanpublic InvalidSessionStrategy invalidSessionStrategy() {return new CustomInvalidSessionStrategy();}@Beanpublic SessionInformationExpiredStrategy expiredSessionStrategy() {return new CustomExpiredSessionStrategy();}
}public class CustomInvalidSessionStrategy implements InvalidSessionStrategy {@Overridepublic void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {// 自定义会话失效处理逻辑response.sendRedirect("/session-invalid"); // 重定向到会话失效页面}
}public class CustomExpiredSessionStrategy implements SessionInformationExpiredStrategy {@Overridepublic void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException {// 自定义会话过期处理逻辑HttpServletResponse response = event.getResponse();response.sendRedirect("/session-expired"); // 重定向到会话过期页面}
}
在上述代码中,通过 invalidSessionStrategy() 方法和 expiredSessionStrategy() 方法分别定义了自定义的会话失效策略和会话过期策略。您可以在相应的自定义策略类中实现自己的会话失效和会话过期处理逻辑。在示例中, CustomInvalidSessionStrategy 类处理会话失效, CustomExpiredSessionStrategy 类处理会话过期。您可以根据实际需求修改这些类来实现您自己的逻辑。
请注意,以上代码只是一个简单的示例,您可以根据实际需求进行更详细的配置和自定义。
5. 源码
查看源码,WebSecurityConfigurerAdapter类的applyDefaultConfiguration()方法,
private void applyDefaultConfiguration(HttpSecurity http) throws Exception {http.csrf();http.addFilter(new WebAsyncManagerIntegrationFilter());//exceptionHandling 方法,这个方法会将 ExceptionHandlingConfigurer 配置进来,// 最终调用 ExceptionHandlingConfigurer#configure 方法将 ExceptionTranslationFilter 添加到 Spring Securityhttp.exceptionHandling();http.headers();//进行session管理http.sessionManagement();http.securityContext();http.requestCache();http.anonymous();http.servletApi();http.apply(new DefaultLoginPageConfigurer<>());http.logout();}public SessionManagementConfigurer<HttpSecurity> sessionManagement() throws Exception {return getOrApply(new SessionManagementConfigurer<>());}
可以看到会话管理是由SessionManagementConfigurer类处理。SessionManagementConfigurer类源码:
public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>extends org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer<SessionManagementConfigurer<H>, H> {//默认策略private final SessionAuthenticationStrategy DEFAULT_SESSION_FIXATION_STRATEGY = createDefaultSessionFixationProtectionStrategy();//策略赋值private SessionAuthenticationStrategy sessionFixationAuthenticationStrategy = this.DEFAULT_SESSION_FIXATION_STRATEGY;/*** Invokes {@link #postProcess(Object)} and sets the* {@link SessionAuthenticationStrategy} for session fixation.* * 默认策略* @param sessionFixationAuthenticationStrategy*/private void setSessionFixationAuthenticationStrategy(SessionAuthenticationStrategy sessionFixationAuthenticationStrategy) {this.sessionFixationAuthenticationStrategy = postProcess(sessionFixationAuthenticationStrategy);}/*** Allows configuring SessionFixation protection* 不同策略初始化* @author Rob Winch*/public final class SessionFixationConfigurer {/*** Specifies that a new session should be created, but the session attributes from* the original {@link HttpSession} should not be retained.* @return the {@link SessionManagementConfigurer} for further customizations*/public SessionManagementConfigurer<H> newSession() {SessionFixationProtectionStrategy sessionFixationProtectionStrategy = new SessionFixationProtectionStrategy();sessionFixationProtectionStrategy.setMigrateSessionAttributes(false);setSessionFixationAuthenticationStrategy(sessionFixationProtectionStrategy);return SessionManagementConfigurer.this;}/*** Specifies that a new session should be created and the session attributes from* the original {@link HttpSession} should be retained.* @return the {@link SessionManagementConfigurer} for further customizations*/public SessionManagementConfigurer<H> migrateSession() {setSessionFixationAuthenticationStrategy(new SessionFixationProtectionStrategy());return SessionManagementConfigurer.this;}/*** Specifies that the Servlet container-provided session fixation protection* should be used. When a session authenticates, the Servlet method* {@code HttpServletRequest#changeSessionId()} is called to change the session ID* and retain all session attributes.* @return the {@link SessionManagementConfigurer} for further customizations*/public SessionManagementConfigurer<H> changeSessionId() {setSessionFixationAuthenticationStrategy(new ChangeSessionIdAuthenticationStrategy());return SessionManagementConfigurer.this;}/*** Specifies that no session fixation protection should be enabled. This may be* useful when utilizing other mechanisms for protecting against session fixation.* For example, if application container session fixation protection is already in* use. Otherwise, this option is not recommended.* @return the {@link SessionManagementConfigurer} for further customizations*/public SessionManagementConfigurer<H> none() {setSessionFixationAuthenticationStrategy(new NullAuthenticatedSessionStrategy());return SessionManagementConfigurer.this;}}
}......
5.1 不同策略的含义
不同的session策略是为了解决会话固定攻击的。会话固定攻击(Session Fixation Attack)是一种安全漏洞,利用该漏洞攻击者可以劫持用户的会话。在Spring Security中,会话固定攻击指的是攻击者在用户登录之前获取到了一个会话ID,并将其注入到用户的浏览器中,然后用户使用该会话ID进行登录。这样,攻击者就可以通过使用相同的会话ID来劫持用户的会话,获取用户的敏感信息或执行恶意操作。为了防止会话固定攻击,Spring Security提供了一些机制,如使用随机生成的会话ID、在用户登录时重新生成会话ID等。这些机制可以有效地保护用户的会话安全。
SessionFixationConfigurer类是Spring Security中的一个配置类,用于配置会话固定攻击保护。它提供了一些方法来配置会话ID的处理方式,以防止会话固定攻击。
- newSession:登录之后创建一个新的session
- migrateSession:登录之后创建一个新的session, 并将旧的session中的数据复制过来
- changeSessionId:不创建新的会话,而是使用由Servlet容器提供的会话固定保护
- none:不做任何的处理,登陆之后沿用就的session
6. 集群模式session管理
在Spring Security集群模式下,可以使用分布式缓存来管理会话。
-
首先,确保你的项目中已经引入了Redis的依赖。
-
在Spring配置文件中配置Redis连接信息:
-
创建一个实现 org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration> 的配置类:
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;@Configuration
@EnableRedisHttpSession
public class SessionConfig {// 可以在这里配置会话过期时间等参数
}
- 在Spring Security配置类中启用会话管理:
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http// 其他Spring Security配置.and().sessionManagement().maximumSessions(1) // 设置允许的最大会话数.maxSessionsPreventsLogin(false) // 当达到最大会话数时,是否阻止新登录.expiredUrl("/session-expired"); // 会话过期后跳转的URL}
}
通过以上配置,Spring Security将会话信息存储在Redis中,实现了会话在集群环境下的管理和共享。你可以根据自己的需求进行相关配置和调整。以上代码只是简单的代码示例,具体使用要根据具体情况而定。
7. 总结
Spring Security会话管理的原理如下:
- 用户登录时,Spring Security会为用户创建一个会话,并生成一个唯一的会话ID。
- 会话ID会被存储在用户的浏览器Cookie中,或者作为请求参数传递给服务器。
- 在后续的请求中,用户会携带会话ID来进行身份验证和授权。
- 服务器接收到请求后,会根据会话ID来查找对应的会话信息。
- 通过会话信息,服务器可以验证用户的身份,并进行相应的授权操作。
- 如果会话过期或被注销,服务器会清除对应的会话信息,并要求用户重新登录。
- Spring Security提供了一些配置选项和机制,如会话超时时间、并发会话控制、会话固定攻击保护等,可以根据需求进行定制和扩展。
通过这种方式,Spring Security实现了对用户会话的管理和安全控制,确保用户的身份验证和授权操作的可靠性和安全性。
相关文章:
SpringSecurity源码学习四:会话管理
目录 1. 什么是会话管理2. springSecurity中的session管理怎么做的3. springSecurity源码中的session管理4. 代码示例5. 源码5.1 不同策略的含义 6. 集群模式session管理7. 总结 1. 什么是会话管理 会话管理是指在Java应用程序中管理用户会话状态的过程。在Spring框架中&#…...
Kotlin笔记(七):协程
1. 协程的定义 协程属于Kotlin中非常有特色的一项技术,因为大部分编程语言中是没有协程这个概念的。 什么是协程呢?它其实和线程是有点类似的,可以简单地将它理解成一种轻量级的线程。要知道,线程是非常重量级的,它需要…...

存储优化知识复习二详细版解析
存储优化 知识复习二 一、 选择题 1、 对数据库调优的方法中,最困难但是最有成效的是( )。 A、优化表的架构设计 B、添加内存 C、索引优化 D、查询语句优化 【参考答案】A2、 防止与处理死锁的方法有( )。 A、尽量避免或尽快处理阻塞 B、访…...

《持续交付:发布可靠软件的系统方法》- 读书笔记(七)
持续交付:发布可靠软件的系统方法(七) 第 7 章 提交阶段7.1 引言7.2 提交阶段的原则和实践7.2.1 提供快速有用的反馈7.2.2 何时令提交阶段失败7.2.3 精心对待提交阶段7.2.4 让开发人员也拥有所有权7.2.5 在超大项目团队中指定一个构建负责人 …...
Go源码实现使用多线程并发下载大文件的功能
摘要:Go语言编码实现了使用多线程并发下载文件的功能。 1. 代码流程介绍 1. 获取系统的CPU核心数量,并将其作为线程数的参考值,并打印出来。 2. 定义要下载的文件的URL、线程数和输出文件名。 3. 使用getFileSize()函数获取文件大小…...

Python基础入门例程1-NP1 Hello World!
描述 将字符串 Hello World! 存储到变量str中,再使用print语句将其打印出来。 输入描述: 无 输出描述: 一行输出字符串Hello World! 解答: str "Hello World!" print(str) 解释说明: 赋值变量&…...
前端面试题10.23
解决的最复杂的前端问题,介绍一下 最复杂的前端问题之一是浏览器兼容性,不同浏览器对网页的渲染方式存在差异,需要针对不同浏览器做兼容性处理。此外,前端性能优化也是一个复杂的问题,需要综合考虑网页加载速度、渲染…...

DYC算法开发与测试(基于ModelBase实现)
ModelBase是经纬恒润开发的车辆仿真软件,包含两个大版本:动力学版本、智能驾驶版本。动力学版包含高精度动力学模型,能很好地复现车辆在实际道路中运行的各种状态变化,可用于乘用车、商用车动力底盘系统算法开发、控制器仿真测试&…...

第四章 路由基础
目录 4.1 路由器概述 4.1.1 路由器定义 4.1.2 路由器工作原理 4.1.3 路由表的生成方式 (1)直连路由 (2)静态路由 (3)动态路由 4.1.4 路由器的接口 (1)配置接口 ࿰…...

Java逻辑运算符(、||和!),Java关系运算符
逻辑运算符把各个运算的关系表达式连接起来组成一个复杂的逻辑表达式,以判断程序中的表达式是否成立,判断的结果是 true 或 false。 逻辑运算符是对布尔型变量进行运算,其结果也是布尔型,具体如表 1 所示。 表 1 逻辑运算符的用…...

三个设备文件
...

Java赋值运算符(=)
赋值运算符是指为变量或常量指定数值的符号。赋值运算符的符号为“”,它是双目运算符,左边的操作数必须是变量,不能是常量或表达式。 其语法格式如下所示: 变量名称表达式内容 在 Java 语言中,“变量名称”和“表达式…...

提升药店效率:山海鲸医药零售大屏的成功案例
在医药行业中,特别是医药零售领域,高效的药品管理和客户服务至关重要。随着科技的飞速发展,数字化解决方案已经成为提高医药零售管控效率的有效工具之一。其中,医药零售管控大屏作为一种强大的工具,正在以独特的方式改…...
使用Fragement(碎片)
一、Fragment简介 屏幕大小的差距可能会使同样的界面在不同设备上显示出不同的效果,为了能同时兼顾到手机和平板电脑的开发,从Android3.0版本开始提供了Fragment。 Fragment(碎片)是一种嵌入在Activity中的UI片段,它…...
种花问题(Python题目)
假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。 给你一个整数数组 flowerbed 表示花坛,由若干 0 和 1 组成,其中 0 …...

STM32入门F4
学习资料:杨桃电子,官网:洋桃电子 | 杜洋工作室 www.doyoung.net 嵌入式开发核心宗旨:以最适合的性能、功能、成本来完成最有性价比的产品开发。 1.为什么要学F407 STM32F103系列与STM32F407系列对照表: 2.F4系列命…...

【30】c++设计模式——>状态模式
状态模式概述 状态模式是一种行为型设计模式,它可以让一个对象在其内部状态发生变化时更改其行为。通过将每个状态封装成一个独立的类,我们可以使状态之间互相独立,并且使得状态的切换变得更加灵活、可扩展。(多个状态之间可以相…...

中文编程开发语言编程实际案例:程序控制灯电路以及桌球台球室用这个程序计时计费
中文编程开发语言编程实际案例:程序控制灯电路以及桌球台球室用这个程序计时计费 上图为:程序控制的硬件设备电路图 上图为:程序控制灯的开关软件截图,适用范围比如:台球厅桌球室的计时计费管理,计时的时候…...
【python】高斯日记
题目: """ 题目描述: 高斯出生于1777年4月30日,记作1777-4-30。在此基础上,我们希望你写一个程序,给定一个数字n,表示从高斯出生的那天算起的第n天,输出这一天的具体日期。例如&…...
[论文笔记]MobileBERT
引言 今天带来一篇关于量化的论文MobileBERT,题目翻译过来是:一种适用于资源有限设备的紧凑型任务无关BERT模型。模型的简称是MobileBERT,意思是作者的这个BERT模型可以部署到手机端。 本篇工作,作者提出了MobileBERT用于压缩和加速BERT模型。与原始BERT一样,MobileBERT…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...