Spring Security -- SecurityContextHolder 详解
前言
SecurityContextHolder 按字面意思理解,就是安全上下文支持。在使用了 Spring Security 的 Spring Boot 应用中,我们在后端想要获取登录用户的信息,可以使用命令:
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
源码分析
这里调用了方法.getContext()
,打开 SecurityContextHolder
的源码,部分源码如下
public class SecurityContextHolder {
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("spring.security.strategy");
private static SecurityContextHolderStrategy strategy;
private static int initializeCount = 0;
...
private static void initialize() {
if (!StringUtils.hasText(strategyName)) {
strategyName = "MODE_THREADLOCAL";
}
if (strategyName.equals("MODE_THREADLOCAL")) {
strategy = new ThreadLocalSecurityContextHolderStrategy();
...
public static SecurityContext getContext() {
return strategy.getContext();
}
...
可以看到,方法.getContext()
来源于 SecurityContextHolderStrategy
,再打开 SecurityContextHolderStrategy
的源码:
package org.springframework.security.core.context;
public interface SecurityContextHolderStrategy {
void clearContext();
SecurityContext getContext();
void setContext(SecurityContext var1);
SecurityContext createEmptyContext();
}
可知 SecurityContestHolderStrategy
只是一个接口,这个接口提供创建、清空、获取、设置上下文的操作。
那它有哪些实现类呢,也就是有哪些存储策略呢?按住 Ctrl + H,查看它的实现类,如下图:
可以看出,SecurityContestHolderStrategy
有三个实现类,分别是
-
ThreadLocalSecurityContextHolderStrategy
-
GlobalSecurityContextHolderStrategy
-
InheritableThreadLocalSecurityContextHolderStrategy
就跟字面意思一样三种策略分别对应 threadlocal,global,InheritableThreadLocal 三种方式。
SecurityContextHolder
默认使用的是 ThreadLocalSecurityContextHolderStrategy
安全策略。
也就是说,方法.getContext()
在接口SecurityContestHolderStrategy
中定义,在类 ThreadLocalSecurityContextHolderStrategy
中实现的。
然后是方法.getAuthentication()
, 按 Ctrl + 鼠标左键,打开源码:
public interface SecurityContext extends Serializable {
Authentication getAuthentication();
void setAuthentication(Authentication var1);
}
接口 SecurityContext
只有 getAuthentication
和 setAuthentication
这两个方法,而这两个方法都是 Authentication
类型。
由源码可知,所谓的安全上下文,只是保存了 Authentication(认证信息),在 Spring Security 使用一个 Authentication 对象来表示这些用户信息。
打开 Authentication
的源码:
public interface Authentication extends Principal, Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean var1) throws IllegalArgumentException;
}
由源码可知,Authentication(认证信息),主要包含了以下内容
-
getAuthorities => 可用于访问受保护资源时的权限验证
-
getCredentials => 初次认证的时候,进行填充,认证成功后将被清空
-
getDetails=> 暂不清楚,猜测应该是记录哪些保护资源已经验证授权,下次不用再验证,等等。
-
Pirncipal => 类似于 UserDetails(用户信息)
-
isAuthenticated => 是否已认证成功
参考资源
https://blog.csdn.net/baidu_38225647/article/details/104396392
https://www.cnblogs.com/longfurcat/p/9417912.html
https://blog.csdn.net/chihaihai/article/details/104830066
每天学习一点点,每天进步一点点。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· 编程神器Trae:当我用上后,才知道自己的创造力被低估了多少
· 开发的设计和重构,为开发效率服务
· 从零开始开发一个 MCP Server!
· Ai满嘴顺口溜,想考研?浪费我几个小时
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密