spring - SecurityContextHolder.getContext().getAuthentication() 如何工作
问题描述
SecurityContextHolder.getContext().getAuthentication()
获取当前经过身份验证的主体,或身份验证请求令牌。但是,我们应该在什么情况下使用它?它是线程安全的吗?例如,如果我们使用静态辅助方法,例如:
public static UserEntity getCurrentUser() {
return (UserEntity)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
使用会安全吗?或者,我们应该只在请求范围的 bean 下使用它?
解决方案
来自 Spring Security 文档:
默认情况下,SecurityContextHolder 使用 ThreadLocal 来存储这些详细信息,这意味着 SecurityContext 始终可用于同一线程中的方法,即使 SecurityContext 没有明确地作为参数传递给这些方法。如果在处理当前主体的请求后注意清除线程,那么以这种方式使用 ThreadLocal 是非常安全的。Spring Security 的 FilterChainProxy 确保 SecurityContext 总是被清除。
根据这个博客:
Java ThreadLocal 类使您能够创建只能由同一线程读取和写入的变量。因此,即使两个线程正在执行相同的代码,并且代码引用了相同的 ThreadLocal 变量,这两个线程也无法看到彼此的 ThreadLocal 变量。因此,Java ThreadLocal 类提供了一种使代码线程安全的简单方法,否则不会如此。
将这些放在一起回答了使用静态 util 方法从 获取当前登录用户是否安全的问题,也就是说,SecurityContextHolder
是的,它是安全的。
推荐阅读
- android - Android - 如何在自由落体结束时找到自由落体持续时间
- oracle - 如何将单个列中的值存储到 oracle 中的单个变量中?
- spring - com.sun.xml.wss.XWSSecurityException:找不到别名“”的证书
- delphi - 如何防止 TStrings.SaveToFile 创建最终的空行?
- android - 尽管存在资源,但 Android 资源链接失败
- python - Python 日志格式化程序
- c# - 将 Xamarin Sndroid 应用程序连接到 SQL 服务器
- laravel - RuntimeException:The "-r" option does not exist
- javascript - javascript选择特定元素
- html - Overlay of div over button with background colour