Spring安全性的SecurityContextHolder:会话或请求绑定?

Userprincipal从SecurityContextHolder检索绑定到请求或会话?

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

这是我访问当前login的用户的方式。 如果当前会话被破坏,这会失效吗?

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

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

SecurityContextPersistenceFilter的Java Doc开始于:

一旦请求完成并清除上下文持有者,就会在请求之前使用从configuration的{@ Security SecurityConpository}获得的信息填充{@link SecurityContextHolder},并将其存储回存储库中。 默认情况下,它使用{@link HttpSessionSecurityContextRepository}。 看到这个类的信息HttpSession相关的configuration选项。

顺便说一句:HttpSessionSecurityContextRepository是SecurityContextRepository的唯一实现(我已经在默认的库中find)

它是这样工作的:

  • HttpSessionSecurityContextRepository使用httpSession(Key =“SPRING_SECURITY_CONTEXT”)来存储一个SecurityContext对象。
  • SecurityContextPersistenceFilter是使用SecurityContextPersistenceFilter的filter,例如HttpSessionSecurityContextRepository来加载和存储SecurityContext对象。 如果HttpRequest通过filter,filter从存储库获取SecurityContext ,并将其置于SecurityContextHolder( SecurityContextHolder#setContext
  • SecurityContextHolder有两个方法setContextgetContext 。 两者都使用SecurityContextHolderStrategy来指定在set-和get-Context方法中完成的工作。 – 例如ThreadLocalSecurityContextHolderStrategy使用本地线程来存储上下文。

所以总结:用户主体(SecurityContext的元素)存储在HTTP会话中。 而且对于每个请求,它都被放置在你访问它的地方的一个线程中。