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

65
我从SecurityContextHolder获取的Userprincipal对象是绑定在请求还是会话上的?
这是我获取当前登录用户的方式:UserPrincipal principal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 如果当前会话被销毁,这种方式是否会失效?
1个回答

119

它取决于您如何配置它(或者说,您可以配置不同的行为)。

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

SecurityContextPersistenceFilter 的 Java Doc 开始的内容如下所示:

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

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

它的工作原理如下:

  • SecurityContextPersistenceFilter是一个过滤器,它使用一个SecurityContextRepository(例如 HttpSessionSecurityContextRepository)来加载和存储SecurityContext对象。如果一个HttpRequest通过了该过滤器,该过滤器将从仓库中获取SecurityContext并将其放入SecurityContextHolder (SecurityContextHolder#setContext)。
  • SecurityContextHolder有两个方法:setContextgetContext。两者都使用一个SecurityContextHolderStrategy来指定在set-和get-Context方法中要执行的操作。例如,ThreadLocalSecurityContextHolderStrategy使用线程本地存储上下文。
  • 因此,总之:用户主体(SecurityContext的元素)存储在HTTP会话中。对于每个请求,它都被放置在线程本地变量中,您可以从那里访问它。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接