Java21 + SpringBoot3使用Spring Security时如何在子线程中获取到认证信息

这篇具有很好参考价值的文章主要介绍了Java21 + SpringBoot3使用Spring Security时如何在子线程中获取到认证信息。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录
  • 前言
  • 原因分析
  • 解决方案
    • 方案1:手动设置线程中的认证信息
    • 方案2:使用DelegatingSecurityContextRunnable创建线程
    • 方案3:修改Spring Security安全策略
      • 通过设置JVM参数修改安全策略
      • 通过SecurityContextHolder修改安全策略
  • 总结

前言

近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统,开发者基于此项目进行裁剪和扩展来完成自己的功能开发。本项目为前后端分离开发,后端基于Java21SpringBoot3开发,后端使用Spring SecurityJWTSpring Data JPA等技术栈,前端提供了vueangularreactuniapp微信小程序等多种脚手架工程。

项目地址:https://gitee.com/breezefaith/fast-alden

在使用Spring Security时,笔者定义了一个ThreadPoolTaskExecutorBean用于创建子线程,但是却遇到了子线程中无法获取到认证信息的问题,本文主要介绍该问题的解决方案。

原因分析

Spring Security中想要获取登录用户信息,只能在当前线程中获取,不能在子线程中获取,其中一个重要的原因就是SecurityContextHolder默认将用户信息保存在ThreadLocal中。

ThreadLocal叫做本地线程变量,意思是说,ThreadLocal中填充的的是当前线程的变量,该变量对其他线程而言是封闭且隔离的,ThreadLocal为变量在每个线程中创建了一个副本,这样每个线程都可以访问自己内部的副本变量。

解决方案

方案1:手动设置线程中的认证信息

在子线程的业务逻辑代码之前先手动设置认证信息,后续就可以通过SecurityContextHolder直接获取。

// 获取当前线程认证信息
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

// 创建新线程
Runnable runnable = new Runnable() {
	public void run() {
		// 手动设置线程中的认证信息
		SecurityContextHolder.getContext().setAuthentication(authentication);
		
		// 线程处理逻辑(后续就能获取到认证信息)
		// ...
	}
};
new Thread(runnable).start();

方案2:使用DelegatingSecurityContextRunnable创建线程

Spring Security考虑到了新线程需要访问认证信息的情况,提供了DelegatingSecurityContextRunnable类,通过该类构建新线程(返回一个Runnable对象),线程内部自然能获取认证信息。有兴趣的读者可以阅读一下DelegatingSecurityContextRunnable的源码,其思路与方法1是一致的,都是先获取到当前线程的认证信息,然后传递给新线程。

// 使用DelegatingSecurityContextRunnable创建线程
Runnable runnable = new DelegatingSecurityContextRunnable(() -> {
  // 线程处理逻辑
  // ...
});
new Thread(runnable).start();

方案3:修改Spring Security安全策略

默认情况下,Spring Security使用ThreadLocal存储认证信息,但实际上它也支持通过设置安全策略来修改认证信息的存储位置,它支持三种安全策略,有MODE_THREADLOCALMODE_INHERITABLETHREADLOCALMODE_GLOBAL。如果没有指定,则会默认使用MODE_THREADLOCAL策略。

  • MODE_THREALOCAL表示用户信息只能由当前线程访问。
  • MODE_INHERITABLETHREADLOCAL表示用户信息可以由当前线程及其子线程访问.。
  • MODE_GLOBAL表示用户信息没有线程限制,全局都可以访问,一般用于gui的开发中。

因此,将安全策略修改为MODE_INHERITABLETHREADLOCAL就可以在子线程中获取到认证信息。

Spring Security还提供了两种修改安全策略的方式,一种是通过设置JVM参数spring.security.strategy,一种是调用SecurityContextHoldersetStrategyName方法。

通过设置JVM参数修改安全策略

-Dspring.security.strategy=MODE_INHERITABLETHREADLOCAL

Java21 + SpringBoot3使用Spring Security时如何在子线程中获取到认证信息

通过SecurityContextHolder修改安全策略

可以借助@PostConstruct注解在程序启动后修改安全策略。

@Configuration
public class CommonSecurityConfig {
    @PostConstruct
    public void setStrategyName() {
        // 程序启动后修改认证信息上下文存储策略,支持子线程中获取认证信息
        SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
    }
}

@PostConstruct注解是由Java提供的,它用来修饰一个非静态的void方法。它会在服务器加载Servlet的时候运行,并且只运行一次。
Java21 + SpringBoot3使用Spring Security时如何在子线程中获取到认证信息

总结

本文主要介绍SpringBoot3使用Spring Security时如何在子线程中获取到认证信息。如有错误,还望批评指正。

在后续实践中我也是及时更新自己的学习心得和经验总结,希望与诸位看官一起进步。文章来源地址https://www.toymoban.com/news/detail-825458.html

到了这里,关于Java21 + SpringBoot3使用Spring Security时如何在子线程中获取到认证信息的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java21 + SpringBoot3集成easy-captcha实现验证码显示和登录校验

    近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统,开发者基于此项目进行裁剪和扩展来完成自己的功能开发。 本项目为前后端分离开发,后端基于 Java21 和 SpringBoot3 开发,后端使用 Spring Security 、 JWT 、 Spr

    2024年01月23日
    浏览(42)
  • SpringBoot如何关闭Spring Security

    在进行springboot项目开发的时候往往需要用到springSecurity 但是在开发阶段我们往往会遇到Security的权限拦截问题 以前用的方法常常是将ip加入白名单的方法 但是其实也有直接关闭security的方法: 直接在Springboot的主启动类增加以下配置 并且注释掉security相关信息: 此时, 则可以正常

    2024年02月12日
    浏览(24)
  • SpringBoot2.7升级项目到Springboot3.1踩坑指南(jdk17/jdk21)

    由于SpringBoot3.x全面拥抱JDK17,兼容jdk21,jdk17乃是大势所趋。这里是从SpringBoot2.7--SpringBoot3.1踩坑指南。 提前阅读:jdk8升级JDK17避坑指南(适用于SpringBoot2.3—SpringBoot2.7升级) 国内顶级开源项目升级到springBoot3情况,可以作为升级SpringBoot3的风向标。仅对比国内规模使用,落地过

    2024年03月09日
    浏览(58)
  • Spring Boot 如何使用 Spring Security 进行认证和授权

    在 Web 应用程序中,认证和授权是非常重要的功能。Spring Security 是一个基于 Spring 框架的强大的安全框架,它提供了完整的认证和授权解决方案,并且可以轻松地集成到 Spring Boot 应用程序中。本文将介绍如何在 Spring Boot 中使用 Spring Security 进行认证和授权,并提供示例代码。

    2024年02月11日
    浏览(29)
  • 手把手教你如何使用SpringBoot3打造一个个性化的代码生成器

    代码基于SpringBoot3、Vue3、highlight实现自定义代码生成功能 SpringBoot3.x、MySQL8、MyBatisPlus3.5.x、velocity2.x、SpringSecurity6.x、Vue3、TypeScript、highlight demo所需要的依赖及其对应版本号 pom 配置文件 这里是最基础的MySQL的配置信息 application 1.1、代码生成器源码目录 这里是代码生成器的源

    2024年01月19日
    浏览(34)
  • 使用Gradle7.6.1 + SpringBoot3.0.2 + java17创建微服务项目(学习)

    这是一个大胆的决定 技术 版本 spring-boot 3.0.2 spring-cloud 2022.0.2 spring-cloud-alibaba 2022.0.0.0-RC2 mybatis-plus-boot-starter 3.5.3.1 mysql-connector-java 8.0.32 技术 版本 java 17 gradle 7.6.1 IDEA 2022.2.4 Nvcat 15 MySQL 8.0.32 打开IDEA创建 SpringBoot项目 删除父项目中的src模块 新建两个子项目(新建时会重新创建

    2024年02月06日
    浏览(72)
  • Spring Boot 中如何使用 Spring Security OAuth2 来实现单点登录

    在现代 Web 应用程序中,单点登录(Single Sign-On,简称 SSO)是一个非常重要的功能。Spring Security OAuth2 是 Spring Security 框架的一个扩展,它提供了一种简单的方式来实现 SSO。在本文中,我们将介绍如何在 Spring Boot 应用程序中使用 Spring Security OAuth2 来实现单点登录。 在开始之前

    2024年02月06日
    浏览(35)
  • 【security】java springboot项目中使用springSecurity安全框架

    springboot项目如果导入security依赖后会自动托管整个项目,前端在访问项目的任何路径时会被拦截并跳转到security默认的登录页面,登录用户名为user,密码为控制台启动项目时生成的随机密码 一、自定义设置用户的认证:创建一个配置类(类上加@Configuration),让该类继承Web

    2024年02月15日
    浏览(47)
  • Springboot +spring security,实现前后端分离,使用JSON数据格式登录(将表单提交方式改成json格式登录)

    在前面的文章中,我们使用表单方式完成登录提交,但是目前基本都是前后端分离项目,很少使用表单提交的方式,基本都是json方式,使用ajax提交,那么我们怎么将表单提交方式改成json格式登录呢? 通过前面源码部分学习中,已经知道在HttpSecurity配置中,每新增一种配置,

    2024年02月06日
    浏览(35)
  • 【SpringBoot3】从重构HelloWorld看Spring的作用

    在我们学习一门新技术的时候,总是先运行出一个基本的程序来输出“Hello World”,如果成功了, 说明我们的开发环境基本就绪了,我们也像婴儿走路一样,能走第一步了。接下来我们就逐步改造一个最基本的HelloWorld来一步步分析Spring到底帮助我们做 了什么。 目录 第一步:

    2024年02月19日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包