【问题标题】:How to set up Spring Security SecurityContextHolder strategy?如何设置 Spring Security SecurityContextHolder 策略?
【发布时间】:2011-03-28 22:19:50
【问题描述】:

我在我的服务中使用异步方法(Spring 3 @Async 注释)。而且我遇到了一个问题 - 生成的线程没有安全上下文。原因是 Spring Security 默认使用 SecurityContextHolder.MODE_THREADLOCAL 策略作为其上下文持有者。但我需要使用SecurityContextHolder.MODE_INHERITABLETHREADLOCAL 策略。 目前我在 AuthenticationSuccessHandler 中设置了策略。但在我看来,这不是一个好习惯。

那么如何在上下文配置文件中进行设置呢?
Spring Security 的版本是 3.0.0。

【问题讨论】:

标签: spring spring-security


【解决方案1】:

通过没有反射的 Java 配置。

import javax.annotation.PostConstruct;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.context.SecurityContextHolder;

@Configuration
public class SecurityConfig {

  @PostConstruct
  public void enableAuthCtxOnSpawnedThreads() {
    SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
  }
}

【讨论】:

    【解决方案2】:

    另一种解决方案,例如@viator write:

    <bean
            class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
            <property name="targetClass"
                value="org.springframework.security.core.context.SecurityContextHolder" />
            <property name="targetMethod" value="setStrategyName" />
            <property name="arguments" value="MODE_INHERITABLETHREADLOCAL" />
        </bean>
    

    像魅力一样工作。

    【讨论】:

      【解决方案3】:

      您可以将环境变量spring.security.strategy 设置为MODE_INHERITABLETHREADLOCAL。您还可以有一个简单的 bean,在您的 Web 应用程序启动期间调用 SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL) 并在您的上下文配置文件中初始化该值。

      SecurityContextHolder API

      【讨论】:

      • 感谢您提供有关简单 bean 的提示。但我为我找到了更方便的解决方案 - 我在安全上下文中添加了以下代码:
      • 我仍然没有配置此 bean 的 httpRequest.getRemoteUser()。
      • 提防影响:如果使用线程池,您还应该使用 setTaskDecorator() 解释这里github.com/spring-projects/spring-security/issues/… 我认为这真的很重要。
      • @FrancoisMarot 感谢您的线程池提示!它拯救了我的后端。使用SecurityContextHolder.MODE_INHERITABLETHREADLOCAL,我的线程池有时无法获取用户上下文。使用executor.setTaskDecorator(runnable -&gt; new DelegatingSecurityContextRunnable(runnable));,似乎总是如此。
      【解决方案4】:

      @viator 的答案的 java 配置如果对你有帮助的话。

      @Bean
      public MethodInvokingFactoryBean methodInvokingFactoryBean() {
          MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
          methodInvokingFactoryBean.setTargetClass(SecurityContextHolder.class);
          methodInvokingFactoryBean.setTargetMethod("setStrategyName");
          methodInvokingFactoryBean.setArguments(new String[]{SecurityContextHolder.MODE_INHERITABLETHREADLOCAL});
          return methodInvokingFactoryBean;
      }
      

      【讨论】:

      • 迟到的评论 :-) 在配置类的某处使用这种 @PostConstruct 是否有优势以确保安全?
      • 我必须看一个例子。 Postconstruct 不会制作 Spring Bean,所以我不确定如何制作?
      • 我的意思是在@PostConstruct 内部调用 SecurityContextHolder.setStrategyName();这都是静态的,所以我猜它可能也会起作用。我得试一试。
      • dev.to/spooz/spring-security-and-threads 的一篇很棒的帖子中有完整的解释,不仅包括@Async,还包括任何自定义线程
      • @hitch.united 查看其他答案:stackoverflow.com/a/65353568/1026624
      猜你喜欢
      • 2019-09-08
      • 1970-01-01
      • 2014-07-26
      • 2018-07-17
      • 1970-01-01
      • 2011-09-18
      • 2015-02-08
      • 2016-01-26
      • 1970-01-01
      相关资源
      最近更新 更多