【问题标题】:How to customize the behaviour of SecurityContextPersistenceFilter?如何自定义 SecurityContextPersistenceFilter 的行为?
【发布时间】:2015-08-27 04:34:08
【问题描述】:

我开发了一个使用基于令牌的身份验证的无状态 REST API,我通过在自定义安全过滤器中调用 SecurityContextHolder.getContext().setAuthentication(authentication) 手动将身份验证对象添加到安全上下文中。我一直遇到上下文设置不正确的问题,我认为这是由于:

Storing the SecurityContext between requests

在单个会话中接收并发请求的应用程序中,相同的 SecurityContext 实例将在线程之间共享。即使使用了 ThreadLocal,它也是从每个线程的 HttpSession 中检索到的同一个实例。如果您希望临时更改线程正在运行的上下文,这会产生影响。如果您只使用 SecurityContextHolder.getContext(),并在返回的上下文对象上调用 setAuthentication(anAuthentication),那么 Authentication 对象将在共享相同 SecurityContext 实例的所有并发线程中发生变化。 ...

您可以自定义 SecurityContextPersistenceFilter 的行为,为每个请求创建一个全新的 SecurityContext,防止一个线程中的更改影响另一个线程。

所以问题是 - 你如何改变 SecurityContextPersistenceFilter 的行为?

我希望安全上下文不与 http 会话关联,但不想将会话创建策略设置为无状态,因为我仍然想实现 CSRF 保护等。

【问题讨论】:

    标签: multithreading spring-security spring-boot servlet-filters security-context


    【解决方案1】:

    今天下午我有这个确切的问题,这个开放的问题与我的搜索完全匹配,所以我想我会添加我学到的一点点。

    我们有线程正在访问同一个 SecurityContext。我无法弄清楚如何直接(以及在框架的模式中)自定义 SecurityContextPersistenceFilter 的行为,但是有两种方法可以让它成为线程安全的。

    第一个解决方案是确保在我们的主要身份验证过滤器中创建一个空上下文。这涵盖了我们所有经过身份验证的请求,因此它适用于我们的解决方案。

    SecurityContextHolder.createEmptyContext();
    

    对我有用的第二件事是将我们的 WebSecurityConfig 更改为无状态,我知道这对 OP 不起作用,但为了完整起见在此处添加。

    http.authorizeRequests()
      .anyRequest().authenticated()
      .and()
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
      ...
    

    对于我们的特定配置,这两种解决方案都独立工作。我确信有第三种解决方案会更好读,但我不知道它是什么,但我想知道。

    这是我第一次发帖。我欢迎任何反馈。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      • 2012-01-05
      • 1970-01-01
      • 1970-01-01
      • 2017-03-04
      • 2019-05-18
      • 1970-01-01
      相关资源
      最近更新 更多