文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SpringSecurity之SecurityContextHolder怎么使用

2023-07-05 13:30

关注

这篇“SpringSecurity之SecurityContextHolder怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“SpringSecurity之SecurityContextHolder怎么使用”文章吧。

介绍

我认为SecurityContextHolder只是为SecurityContext提供一种存储策略,只是主导了他的存储方式及地址。

使用中我们表面上看起来SecurityContext的存储都是通过SecurityContextHolder在控制人们就习以为常的说成了Security Context存储在了SecurityContextHolder中,至于真相我们看源码慢慢分析。

public class SecurityContextHolder {// ~ Static fields/initializers// =====================================================================================public static final String MODE_THREADLOCAL = "MODE_THREADLOCAL";public static final String MODE_INHERITABLETHREADLOCAL = "MODE_INHERITABLETHREADLOCAL";public static final String MODE_GLOBAL = "MODE_GLOBAL";public static final String SYSTEM_PROPERTY = "spring.security.strategy";private static String strategyName = System.getProperty(SYSTEM_PROPERTY);private static SecurityContextHolderStrategy strategy;private static int initializeCount = 0;

首先从源码可以看到SecurityContextHolder提供了一个SecurityContextHolderStrategy存储策略进行上下文的存储,进入到Security ContextHolderStrategy接口,由下图我们可以清晰的看到其总共有三个实现类。

分别对应三种存储策略,这里我不知道为什么99的文章都只说了threadlocal和global两种。

要不是看了下实现类我都信了。

SpringSecurity之SecurityContextHolder怎么使用

就跟字面意思一样三种策略分别对应threadlocal,global,InheritableThreadLocal三种方式。

继续回到源码我们详细看这三种方式。

private static void initialize() {if (!StringUtils.hasText(strategyName)) {// 如果没有设置自定义的策略,就采用MODE_THREADLOCAL模式strategyName = MODE_THREADLOCAL;}// ThreadLocal策略if (strategyName.equals(MODE_THREADLOCAL)) {strategy = new ThreadLocalSecurityContextHolderStrategy();}// 采用InheritableThreadLocal,它是ThreadLocal的一个子类else if (strategyName.equals(MODE_INHERITABLETHREADLOCAL)) {strategy = new InheritableThreadLocalSecurityContextHolderStrategy();}// 全局策略,实现方式就是static SecurityContext contextHolderelse if (strategyName.equals(MODE_GLOBAL)) {strategy = new GlobalSecurityContextHolderStrategy();}else {// Try to load a custom strategy  自定义的策略,通过返回创建出try {Class<?> clazz = Class.forName(strategyName);Constructor<?> customStrategy = clazz.getConstructor();strategy = (SecurityContextHolderStrategy) customStrategy.newInstance();}catch (Exception ex) {ReflectionUtils.handleReflectionException(ex);}}initializeCount++;}

由源码我们可以得出SecurityContextHolder 默认使用的是THREADLOCAL模式,光从名字看感觉就是存储在threadlocal中的策略到底是不是我们去源码中分别一探究竟:

ThreadLocalSecurityContextHolderStrategy

final class ThreadLocalSecurityContextHolderStrategy implementsSecurityContextHolderStrategy {// ~ Static fields/initializers// =====================================================================================private static final ThreadLocal<SecurityContext> contextHolder = new ThreadLocal<>();。。。。。。}

InheritableThreadLocalSecurityContextHolderStrategy

final class InheritableThreadLocalSecurityContextHolderStrategy implementsSecurityContextHolderStrategy {// ~ Static fields/initializers// =====================================================================================private static final ThreadLocal<SecurityContext> contextHolder = new InheritableThreadLocal<>();。。。。。。}

GlobalSecurityContextHolderStrategy

final class GlobalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {// ~ Static fields/initializers// =====================================================================================private static SecurityContext contextHolder;。。。。。。}

到这里那些说SecurityContext存储在SecurityContextHolder的大佬们我认为应该是不严谨的。

默认是将SecurityContext存储在threadlocal中,可能是spring考虑到目前大多数为BS应用,一个应用同时可能有多个使用者,每个使用者又对应不同的安全上下,Security Context Holder为了保存这些安全上下文。

缺省情况下,使用了ThreadLocal机制来保存每个使用者的安全上下文。

因为缺省情况下根据Servlet规范,一个Servlet request的处理不管经历了多少个Filter,自始至终都由同一个线程来完成。这样就很好的保证了其安全性。

但是当我们开发的是一个CS本地应用的时候,这种模式就不太适用了。

spring早早的就考虑到了这种情况,这个时候我们就可以设置为Global模式仅使用一个变量来存储SecurityContext。比如还有其他的一些应用会有自己的线程创建,并且希望这些新建线程也能使用创建者的安全上下文。

这种效果,我们就可以通过将SecurityContextHolder配置成MODE_INHERITABLETHREADLOCAL策略达到。

以上就是关于“SpringSecurity之SecurityContextHolder怎么使用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯