Spring Security 如何跨 Web 应用程序请求在线程中管理 SecurityContext?

Posted

技术标签:

【中文标题】Spring Security 如何跨 Web 应用程序请求在线程中管理 SecurityContext?【英文标题】:How does Spring Security manage SecurityContext in a thread across web application requests? 【发布时间】:2011-11-02 15:28:22 【问题描述】:

在 SpringSecurity 中,它有一个类名 SecurityContextHolder 及其规范:“将给定的 SecurityContext 与当前执行线程相关联。”每当请求到达服务器时,使用 Web 应用程序时,Spring 还会在 SecurityContextHolder 中为其线程重新加载并设置该请求的 SecurityContext 吗?

【问题讨论】:

请看***.com/questions/6408007/… 【参考方案1】:

是的,SecurityContextPersistenceFilter 会处理这个问题。默认情况下,它在 HttpSession 中定位 SecurityContext,并通过 SecurityContextHolder 将其绑定到线程。当请求完成处理时,它会执行相反的操作 - 它从线程中获取 SecurityContext 并将其放入会话中。

来自 Javadoc:

使用从 在请求和存储之前配置 SecurityContextRepository 请求完成并清除后,它会返回存储库 上下文持有者。默认情况下,它使用 HttpSessionSecurityContextRepository。

【讨论】:

不应该让它也线程安全吗?似乎SecurityContext 没有在我的应用程序中的线程之间共享(link)。【参考方案2】:

每当请求到达服务器时,使用 Web 应用程序时,Spring 还会在 SecurityContextHolder 中为其线程重新加载并设置该请求的 SecurityContext 吗?

基本上是的。

SecurityContextHolder.getInstance() 的默认行为是返回一个 SecurityContextHolder 实例,它存储为当前线程的线程本地。 (这只是默认机制。您可以通过调用SecurityContextHolder.setStrategemName() 来使用不同的策略来定位SecurityContextHolder

SpringSecurity 过滤器确保请求的SecurityContextHolder(无论它位于何处)在开始时就加载了请求凭据,并且在请求处理结束时清除了持有者。

【讨论】:

详细说明,关键是过滤器在远程调用属性中查找安全上下文。只有在远程调用属性中存在安全上下文时,才能在 SecurityContextHolder 中设置它。此安全上下文通常由具有类似过滤器的客户端提供,该过滤器处理传出调用并将安全上下文从本地线程放入远程调用。 Why is this not working 给我?见*** question。

以上是关于Spring Security 如何跨 Web 应用程序请求在线程中管理 SecurityContext?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security系列教程解决Spring Security环境中的跨域问题

使用 Grails 和 Spring Security 进行跨域身份验证

在进行跨域请求时,如何使用 SockJS 和 STOMP 添加 Spring Security JSESSIONID?

springboot2.1.3整合websocket和websocket-security支持跨域连接

spring security之web应用安全

如何在 Spring Web App 中临时禁用 Spring Security