当前位置: 首页 > news >正文

Spring Security OAuth2.0(9):会话控制

Spring Security 提供了多种会话控制(Session Management)方式,用于管理用户认证后的会话行为,包括会话创建、固定、并发控制等。以下是主要的会话控制方式及其配置方法:


1. 会话创建策略(Session Creation Policy)

通过HttpSecurity.sessionManagement().sessionCreationPolicy()设置会话的创建规则:

  • always
    如果请求未携带会话,则总是创建新会话(默认行为)。

    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
  • ifRequired
    仅在需要时创建会话(如未认证用户提交表单时)。

    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
  • **never`
    Spring Security 不会创建会话,但会使用已存在的会话(适用于无状态 API,如 RESTful 服务)。

    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
  • stateless
    完全无状态,不创建也不使用会话(适用于 JWT 等 Token 认证)。

    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

2. 会话固定保护(Session Fixation Protection)

防止会话固定攻击(攻击者通过固定会话 ID 劫持用户会话):

  • migrateSession(默认)
    认证成功后创建新会话,复制原会话属性到新会话。

    http.sessionManagement().sessionFixation().migrateSession();
  • newSession
    认证后创建全新会话,不复制原属性。

    http.sessionManagement().sessionFixation().newSession();
  • none
    禁用保护,不更改会话(不推荐)。

    http.sessionManagement().sessionFixation().none();

3. 并发会话控制(Concurrent Session Control)

限制同一用户可同时登录的会话数量:

  • 配置会话注册表
    使用SessionRegistry跟踪活跃会话:

    @BeanpublicSessionRegistrysessionRegistry(){returnnewSessionRegistryImpl();}
  • 限制并发会话数
    通过maximumSessions设置最大会话数,expiredUrl指定会话过期后的跳转页面:

    http.sessionManagement().maximumSessions(1)// 最多允许1个会话.expiredUrl("/login?error=EXPIRED_SESSION");// 会话过期跳转.invalidSessionUrl("/login?error=INVALID_SESSION");// 无效会话
  • 禁止新登录踢出旧会话
    添加maxSessionsPreventsLogin(true)阻止新登录:

    http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true);// 新登录失败(返回403)
  • 手动管理会话
    通过SessionRegistry获取或注销会话:

    @AutowiredprivateSessionRegistrysessionRegistry;publicvoidlogoutUser(Stringusername){List<SessionInformation>sessions=sessionRegistry.getAllSessions(username,false);sessions.forEach(session->session.expireNow());// 使会话过期}

4. 会话超时控制

通过 Spring Boot 或 Servlet 容器配置会话超时:

  • Spring Boot 配置
    application.properties中设置:

    server.servlet.session.timeout=30m # 30分钟超时
  • Servlet 容器配置
    web.xml中设置(传统方式):

    <session-config><session-timeout>30</session-timeout><!-- 单位:分钟 --></session-config>

5. 自定义会话属性

在认证成功后向会话添加自定义属性:

publicclassCustomAuthenticationSuccessHandlerimplementsAuthenticationSuccessHandler{@OverridepublicvoidonAuthenticationSuccess(HttpServletRequestrequest,HttpServletResponseresponse,Authenticationauthentication){request.getSession().setAttribute("USER_ROLE",authentication.getAuthorities());}}// 配置http.formLogin().successHandler(newCustomAuthenticationSuccessHandler());

6. 禁用 URL 重写(防止 CSRF)

禁用会话 ID 在 URL 中暴露(默认已禁用,需显式配置):

http.sessionManagement().disableUrlRewriting();// 禁用 jsessionid=xxx 参数

完整配置示例

@Configuration@EnableWebSecuritypublicclassSecurityConfig{@BeanpublicSessionRegistrysessionRegistry(){returnnewSessionRegistryImpl();}@Overrideprotectedvoidconfigure(HttpSecurityhttp)throwsException{http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).sessionFixation().migrateSession().maximumSessions(1).expiredUrl("/login?expired=true").sessionRegistry(sessionRegistry()).and().authorizeRequests().antMatchers("/public/**").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login").permitAll();}}

总结

  • 会话创建:根据场景选择ALWAYSIF_REQUIREDNEVERSTATELESS
  • 会话固定:推荐使用migrateSessionnewSession
  • 并发控制:通过SessionRegistrymaximumSessions限制多登录。
  • 超时:结合 Spring Boot 或容器配置。
  • 无状态:REST API 推荐STATELESS+ Token(如 JWT)。

根据实际需求选择合适的组合,确保安全性和用户体验平衡。

安全会话cookie

我们可以使用httpOnly 和secure 标签来保护我们的会话cookie

  • httpOnly 如果为true ,那么浏览器脚本将无法访问cookie
  • secure 如果为true,则cookie将仅通过https链接发送

springboot配置文件

# 会话 Cookie 配置 server.servlet.session.cookie.secure=true # 仅 HTTPS 传输 server.servlet.session.cookie.http-only=true # 禁止 JavaScript 访问
http://www.jsqmd.com/news/460887/

相关文章:

  • 一天一个开源项目(第46篇):Caddy - 自动 HTTPS 的现代化 Web 服务器,支持 HTTP/3
  • MySQL 的存储引擎有哪些?它们之间有什么区别
  • Linux I/O重定向
  • STM32驱动LCD1602A
  • P8623 [蓝桥杯 2015 省 B] 移动距离【数学】
  • MySQL 国产数据库替换指南(内附四大MySQL主流厂商对比 )
  • B+树的层数与I/O次数:一场从楼梯到电梯的旅程
  • 基于springboot的智能推荐卫生健康系统的设计与实现项目源码 java毕设 免费分享
  • 基于springboot的人事系统的设计与实现项目源码 java毕设 免费分享
  • 踩坑实录:我是如何被MySQL配置文件里一个看不见的字符坑到下班的
  • 哆哆Excel插件:数字文本转化与格式化(附VB.NET源代码)
  • AI原生应用在计算机视觉中的独特优势
  • Java SpringBoot+Vue3+MyBatis 党员学习交流平台系统源码|前后端分离+MySQL数据库
  • Java SpringBoot+Vue3+MyBatis 福泰轴承股份有限公司进销存系统系统源码|前后端分离+MySQL数据库
  • Python高级编程技术:深度解析与实战指南
  • 2026年集成电路产业博览会报名入口与参展流程详细说明 - 品牌2026
  • Flutter 三方库 code_builder 的鸿蒙化适配指南 - 实现具备流式语法抽象的代码自动生成引擎、支持端侧元编程与高性能插件开发实战
  • Flutter 三方库 strobe 的鸿蒙化适配指南 - 实现高性能异步流监听、支持防抖与频率控制的流控方案
  • 突破Cursor功能限制:从技术探秘到实战应用的完整指南
  • 基于WOA鲸鱼优化的NARMAX模型参数辨识算法MATLAB仿真,对比PSO优化算法
  • OpenClaw下载安装教程
  • utorrent官网安装包下载
  • STM32F103C8T6驱动MPU6050姿态传感器程序
  • DAMO-YOLO手机检测系统沙箱环境:Docker隔离运行保障主机安全
  • Hive分区与分桶:大数据存储优化的关键策略
  • Jimeng AI Studio GPU算力适配方案:A10显存12GB稳定运行4K生成实测
  • OpenClaw安装方式大对比!选对方式不踩坑!!!
  • 泰山派开发板:开箱即用的国产高性能嵌入式平台简介
  • Qwen3-ASR-1.7B模型剪枝实战:体积缩小60%性能保持方案
  • 太强了!这份Java面试八股文帮418人拿下大厂Offer,金三银四必看!!!