Spring Security的SecurityContextHolder:会话还是请求绑定?

2022-08-31 15:10:00

我从中检索的用户原则是否绑定到请求或会话?SecurityContextHolder

UserPrincipal principal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

这是我访问当前登录用户的方式。如果当前会话被销毁,这会失效吗?


答案 1

这取决于你如何配置它(或者比方说,你可以配置一个不同的行为)。

在Web应用程序中,您将使用ThreadLocalSecurityContextHolderStrategy,它与SecurityContextPersistenceFilter交互。

的 Java 文档以以下开头:SecurityContextPersistenceFilter

在请求之前,使用从配置的 {@link SecurityContextRepository} 获取的信息填充 {@link SecurityContextHolder},并在请求完成后将其存储回存储库中并清除上下文持有者。默认情况下,它使用 {@link HttpSessionSecurityContextRepository}。有关 HttpSession 相关配置选项的信息,请参阅此类。

顺便说一句:HttpSessionSecurityContextRepository是SecurityContextRepository的唯一实现(我在默认的libs中找到)

它的工作原理如下:

  • HttpSessionSecurityContextRepository使用httpSession(Key=“SPRING_SECURITY_CONTEXT”)来存储对象。SecurityContext
  • 是一个过滤器,例如使用 来加载和存储对象。如果 HttpRequest 通过过滤器,过滤器将从存储库中获取 过滤器,并将其放在 SecurityContextHolder (SecurityContextPersistenceFilterSecurityContextRepositoryHttpSessionSecurityContextRepositorySecurityContextSecurityContextSecurityContextHolder#setContext)
  • 有两种方法和 。两者都使用 a 来指定在 set 和 get-Context 方法中确切执行的操作。- 例如,使用本地线程来存储上下文。SecurityContextHoldersetContextgetContextSecurityContextHolderStrategyThreadLocalSecurityContextHolderStrategy

总而言之:用户主体(SecurityContext的元素)存储在HTTP会话中。对于每个请求,它都放在您访问它的本地线程中。


答案 2

推荐