首页 > 解决方案 > SecurityContextHolder.getContext().getAuthentication() 如何工作

问题描述

SecurityContextHolder.getContext().getAuthentication()获取当前经过身份验证的主体,或身份验证请求令牌。但是,我们应该在什么情况下使用它?它是线程安全的吗?例如,如果我们使用静态辅助方法,例如:

public static UserEntity getCurrentUser() {
        return (UserEntity)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}

使用会安全吗?或者,我们应该只在请求范围的 bean 下使用它?

标签: springspring-mvcspring-security

解决方案


来自 Spring Security 文档:

默认情况下,SecurityContextHolder 使用 ThreadLocal 来存储这些详细信息,这意味着 SecurityContext 始终可用于同一线程中的方法,即使 SecurityContext 没有明确地作为参数传递给这些方法。如果在处理当前主体的请求后注意清除线程,那么以这种方式使用 ThreadLocal 是非常安全的。Spring Security 的 FilterChainProxy 确保 SecurityContext 总是被清除。

根据这个博客

Java ThreadLocal 类使您能够创建只能由同一线程读取和写入的变量。因此,即使两个线程正在执行相同的代码,并且代码引用了相同的 ThreadLocal 变量,这两个线程也无法看到彼此的 ThreadLocal 变量。因此,Java ThreadLocal 类提供了一种使代码线程安全的简单方法,否则不会如此。

将这些放在一起回答了使用静态 util 方法从 获取当前登录用户是否安全的问题,也就是说,SecurityContextHolder是的,它是安全的


推荐阅读