最新Spring Security实战教程(十三)会话管理机制 - 并发控制与会话固定攻击防护

最新Spring Security实战教程(十三)会话管理机制 - 并发控制与会话固定攻击防护
在这里插入图片描述
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏19年编写主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
🌛《开源项目》本专栏主要介绍目前热门的开源项目,带大家快速了解并轻松上手使用
✨《开发技巧》本专栏包含了各种系统的设计原理以及注意事项,并分享一些日常开发的功能小技巧
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
🌞《Spring Security》专栏中我们将逐步深入Spring Security的各个技术细节,带你从入门到精通,全面掌握这一安全技术
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

最新Spring Security实战教程(十三)会话管理机制 - 并发控制与会话固定攻击防护

回顾链接:
最新Spring Security实战教程(一)初识Spring Security安全框架
最新Spring Security实战教程(二)表单登录定制到处理逻辑的深度改造
最新Spring Security实战教程(三)Spring Security 的底层原理解析
最新Spring Security实战教程(四)基于内存的用户认证
最新Spring Security实战教程(五)基于数据库的动态用户认证传统RBAC角色模型实战开发
最新Spring Security实战教程(六)最新Spring Security实战教程(六)基于数据库的ABAC属性权限模型实战开发
最新Spring Security实战教程(七)方法级安全控制@PreAuthorize注解的灵活运用
最新Spring Security实战教程(八)Remember-Me实现原理 - 持久化令牌与安全存储方案
最新Spring Security实战教程(九)前后端分离认证实战 - JWT+SpringSecurity无缝整合
最新Spring Security实战教程(十)权限表达式进阶 - 在SpEL在安全控制中的高阶魔法
最新Spring Security实战教程(十一)CSRF攻防实战 - 从原理到防护的最佳实践
最新Spring Security实战教程(十二)CORS安全配置 - 跨域请求的安全边界设定

专栏更新完毕后,博主将会上传所有章节代码到ZEEKLOG资源免费给大家下载,如你不想等后续章节代码需提前获取,可以私信或留言!

1. 前言

在Web应用安全体系中,会话管理是认证授权后的重要防线。攻击者常通过会话劫持会话固定突破系统边界,而业务系统则面临并发滥用带来的资源风险。

Spring Security 的会话管理模块由 SessionManagementFilter 与一系列 SessionAuthenticationStrategy 共同协作,负责在用户登录或访问受保护资源时执行统一的会话检查与策略​。默认情况下,框架允许单个用户拥有无限多个并发会话,而在每次登录时会执行会话固定保护策略,将旧 Session ID 迁移到新 Session 中,以防止攻击者利用已有的 Session ID 进行劫持。

在本章节博主将基于 Spring Security 6,带着小伙伴深入解析会话管理的安全实践。


2. 会话固定攻击防护原理

2.1 攻击概述

会话固定(Session Fixation)指攻击者诱导受害者在已知的 Session ID 下登录,随后持该 ID 进行未授权操作。Spring Security 通过 会话固定保护策略,在每次用户登录后刷新 Session ID 来防御此类攻击

攻击流程解析:

在这里插入图片描述

2.2 Spring Security防御策略

SessionManagementFilter 在认证成功后,会调用相应的 SessionAuthenticationStrategy,执行上述策略。migrateSession() 在底层通过 HttpServletRequest.changeSessionId()复制属性到新 Session 来实现 ID 刷新,有效防止攻击者使用固定 ID 进行入侵

配置样例

@Configuration@EnableWebSecuritypublicclassSecurityConfig{@BeanpublicSecurityFilterChainsecurityFilterChain(HttpSecurity http)throwsException{ http // 启用会话固定防护,采用迁移会话策略.sessionManagement(session -> session .sessionFixation(fix -> fix.migrateSession()// 默认:保留旧数据,生成新 Session ID// fix.changeSessionId // 变更会话ID// fix.newSession() // 完全新建 Session,不保留任何属性// fix.none() // 禁用保护(不推荐))).authorizeHttpRequests(auth -> auth .anyRequest().authenticated());return http.build();}}

配置说明

none:不做任何处理,不推荐使用changeSessionId:认证后变更会话IDnewSession:创建全新、干净的 Session,不复制原属性;migrateSession(默认):创建新 Session 并复制原有属性,保留必要数据同时更换 ID,防范攻击者利用旧 ID

3. 并发会话控制方案

当同一账号在多个地方登录后,可能带来数据冲突、授权混乱甚至资源浪费。Spring Security 通过并发会话控制,可限制用户的最大在线会话数,并在超过限制时选择“踢出旧会话”或“拒绝新登录”两种策略

3.1 为什么要限制并发会话?

  • 防止账号共享:同一账号在多处登录可能意味着凭证泄露;
  • 防范会话劫持:一旦旧会话被劫持,可通过限制数量来自动踢出旧会话

3.2 核心组件

  • SessionRegistry:维护用户与其活跃 Session 的映射;
  • ConcurrentSessionControlAuthenticationStrategy:在用户登录时检查并发会话数量,超过上限可抛出 SessionAuthenticationException 或踢出最早会话;
  • HttpSessionEventPublisher:侦听 HttpSessionEvent,在 Session 销毁时同步更新 SessionRegistry

3.3 配置样例

@Configuration@EnableWebSecuritypublicclassSecurityConfig{// 1. 注册Session事件监听器,以使 Spring Security 能够及时了解会话生命周期事件@BeanpublicHttpSessionEventPublisherhttpSessionEventPublisher(){returnnewHttpSessionEventPublisher();}@BeanpublicSecurityFilterChainfilterChain(HttpSecurity http)throwsException{ http .sessionManagement(session -> session .maximumSessions(1)// 同一用户仅允许 1 个会话.maxSessionsPreventsLogin(true)// 超出拒绝后续登录;false 则踢出最早会话.expiredUrl("/login?expired")// 会话过期后重定向地址);return http.build();}}

4. 测试验证方案

为了演示本次并发控制与会话固定攻击防护的功能,这里博主借鉴官方的样例代码稍做调整进行演示

官方样例代码:https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/session-management/maximum-sessions

❶ 确保引入spring-security-test

<dependencies><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-test</artifactId></dependency></dependencies>

❷ 编写配置类

@Configuration@EnableWebSecuritypublicclassSessionSecurityConfig{// 1. 注册Session事件监听器,以使 Spring Security 能够及时了解会话生命周期事件@BeanpublicHttpSessionEventPublisherhttpSessionEventPublisher(){returnnewHttpSessionEventPublisher();}@BeanpublicSecurityFilterChainfilterChain(HttpSecurity http)throwsException{ http .authorizeHttpRequests((authorizeRequests)-> authorizeRequests .anyRequest().authenticated()).formLogin(withDefaults()).sessionManagement(session -> session .sessionFixation(sf -> sf.migrateSession()).maximumSessions(1)// 同一用户仅允许 1 个会话.maxSessionsPreventsLogin(true)// 超出拒绝后续登录;false 则踢出最早会话.expiredUrl("/login?expired")// 会话过期后重定向地址);return http.build();}@BeanpublicUserDetailsServiceuserDetailsService(){UserDetails user =User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build();returnnewInMemoryUserDetailsManager(user);}}

❸ 编写测试请求

@RestControllerpublicclassHomeController{@GetMapping("/")publicStringhello(){return"hello";}}

❹ 编写测试类

importcom.toher.springsecurity.demo.session.management.DemoSessionApplication;importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.mock.web.MockHttpSession;importorg.springframework.test.web.servlet.MockMvc;importorg.springframework.test.web.servlet.MvcResult;importstaticorg.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;importstaticorg.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;importstaticorg.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;importstaticorg.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;/** * @Description: * @Auther: Micro麦可乐 */@SpringBootTest(classes =DemoSessionApplication.class)// 替换为实际的主配置类@AutoConfigureMockMvcpublicclassSessionConcurrencyTest{@AutowiredprivateMockMvc mockMvc;@TestvoidtestConcurrentLogin()throwsException{// 第一次登录MvcResult mvcResult = mockMvc.perform(formLogin()).andExpect(authenticated()).andReturn();MockHttpSession firstLoginSession =(MockHttpSession) mvcResult.getRequest().getSession(); mockMvc.perform(get("/").session(firstLoginSession)).andExpect(authenticated());// 第二次登录将被拒绝 mockMvc.perform(formLogin()).andExpect(authenticated());// 验证第一次会话已失效 mockMvc.perform(get("/").session(firstLoginSession)).andExpect(unauthenticated());}}

❺ 并行运行测试

我们需要观察控制台信息返回,小伙伴可以调整 .maxSessionsPreventsLogin(true) 值以测试第二次登陆是拒绝,还是退出最早会话
第一次登陆请求

测试请求获取数据

再次登陆发起请求返回登陆页

❻ 会话固定攻击模拟

# 获取初始会话IDcurl -I http://localhost:8080/login Set-Cookie: JSESSIONID=12345;Path=/; HttpOnly # 使用固定会话ID尝试认证curl -X POST http://localhost:8080/login \ -H "Cookie: JSESSIONID=12345"\ -d "username=admin&password=123456"# 验证响应是否生成新会话ID Set-Cookie: JSESSIONID=67890;Path=/; HttpOnly 
以该 ID 发起登录请求,登录后检查返回的 Set-Cookie 中 Session ID 是否已更换,验证 ID 刷新策略

5. 会话事件监听器

很多时候我们会话失效我们会进行一些操作,如:日记记录,那么就可以会话事件监听器来实现,如

@ComponentpublicclassSessionActivityListenerimplementsApplicationListener<SessionDestroyedEvent>{@OverridepublicvoidonApplicationEvent(SessionDestroyedEvent event){ event.getSecurityContexts().forEach(context ->{AuditLog.log("会话终止", context.getAuthentication().getName(),"原因: "+ event.getSessionId());});}}

6. 结语

通过本章节的讲解配置与实战示例,结合 sessionFixation().migrateSession()maximumSessions(...) 等配置,相信小伙伴已掌握 Spring Security 的并发会话控制与会话固定防护策略,能够为应用构建坚实的会话安全防线。

如果你在实践过程中有任何疑问或更好的扩展思路,欢迎在评论区留言,最后希望大家 一键三连 给博主一点点鼓励!


Read more

Flutter 三方库 github_actions_toolkit 的鸿蒙化适配指南 - 实现 GitHub Actions 高效自动化任务构建、支持日志颜色修饰与核心工具集成

Flutter 三方库 github_actions_toolkit 的鸿蒙化适配指南 - 实现 GitHub Actions 高效自动化任务构建、支持日志颜色修饰与核心工具集成

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 github_actions_toolkit 的鸿蒙化适配指南 - 实现 GitHub Actions 高效自动化任务构建、支持日志颜色修饰与核心工具集成 前言 在进行 Flutter for OpenHarmony 的工程化 CI/CD(持续集成与交付)构建时,利用 GitHub Actions 进行自动化测试和流水线发布是主流选择。github_actions_toolkit 是一个专为编写非 Web 类 Action 脚本设计的工具集,它能让你在 Dart 脚本中轻松调用 Actions 的核心功能(如日志分级输出、设置导出变量等)。本文将探讨如何利用该库提升鸿蒙项目的自动化构建效率。 一、原理解析 / 概念介绍

By Ne0inhk
深度解析英伟达最新“瓦力”机器人:物理AI时代的开发者红利与技术突破

深度解析英伟达最新“瓦力”机器人:物理AI时代的开发者红利与技术突破

2026年CES展会上,黄仁勋牵着那款酷似《机器人总动员》“瓦力”的Reachy Mini机器人完成流畅互动时,全场的欢呼不仅是对萌系设计的认可,更是对一个新时代的致敬——英伟达用这套全新机器人系统,正式宣告物理AI从实验室走向产业化。对于咱们ZEEKLOG的开发者而言,这波技术浪潮带来的不只是视觉震撼,更是可落地的开发工具、开源生态和商业机遇。今天就从技术内核、开发价值、行业对比三个维度,深度拆解英伟达最新机器人的核心竞争力,帮大家找准入局切入点。 一、不止“萌出圈”:英伟达新机器人的技术内核拆解 很多人被“瓦力”的外形圈粉,但真正让行业震动的是其背后的全栈技术体系。不同于传统机器人“硬件堆砌+单一功能编程”的模式,英伟达这套系统是“大脑-身体-训练场”的全链路协同,每一个环节都为开发者预留了创新空间。 1. 核心大脑:GR00T N1.6模型的双系统突破 作为全球首个开源人形机器人基础模型,最新的Isaac GR00T N1.6堪称“机器人界的GPT-4o”,其最核心的创新是双系统架构设计,完美复刻了人类“本能反应+深度思考”

By Ne0inhk

HY-MT1.5-1.8B嵌入式部署:无人机多语言播报系统开发实录

HY-MT1.5-1.8B嵌入式部署:无人机多语言播报系统开发实录 随着人工智能在边缘计算场景的深入应用,轻量化大模型的落地成为智能硬件发展的关键突破口。特别是在无人机、移动巡检、跨境物流等需要实时交互的领域,多语言自动播报系统的需求日益增长。腾讯开源的混元翻译大模型 HY-MT1.5-1.8B 凭借其高精度与低延迟的特性,为嵌入式多语言翻译提供了全新可能。本文将基于实际项目经验,详细记录如何在资源受限的无人机平台上部署 HY-MT1.5-1.8B 模型,构建一套支持33种语言实时播报的嵌入式系统,涵盖技术选型、模型优化、代码实现与性能调优全过程。 1. 技术背景与业务需求 1.1 无人机多语言播报的挑战 在国际展会、跨境景区或应急救援等场景中,无人机常需向不同语言背景的人群进行广播提示。传统方案依赖预录音频或云端翻译服务,存在以下痛点: * 延迟高:依赖网络请求云端API,响应时间不可控 * 离线不可用:无网络环境下无法工作 * 成本高:频繁调用商业翻译API费用昂贵 * 定制性差:难以根据上下文动态调整术语和语气 因此,亟需一种本地化、低延迟、可定制的多语言翻

By Ne0inhk

OpenClaw安装和接入飞书机器人完整教程

OpenClaw安装和接入飞书机器人分三大部分组织回答: 1)先讲环境准备和OpenClaw基础安装(分阿里云和本地Windows两种场景); 2)再讲飞书机器人配置(包括应用创建、通道添加、事件订阅); 3)最后讲验证和配置AI模型。 为了更直观,在部署方式对比、配置项说明等地方用表格呈现。 这是一份完整的OpenClaw安装及接入飞书机器人的教程。将涵盖从环境准备、OpenClaw部署(含阿里云服务器和本地Windows两种方式)、AI模型(以阿里云百炼为例)配置,到最终在飞书开放平台创建并接入机器人的全流程。 第一部分:准备工作与核心认知 在开始动手前,我们需要先了解 OpenClaw 是什么,并准备好必要的账号和工具。 1.1 什么是 OpenClaw? OpenClaw(昵称“小龙虾”,曾用名 ClawdBot / Moltbot)是一个开源的个人AI智能体框架。它本身不具备推理能力,需要对接大语言模型(如阿里云百炼、七牛云、OpenAI等)的API。它的核心价值在于: * 真正的执行能力:能通过“技能”

By Ne0inhk