Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何建立Spring Security ContextHolder策略?_Spring_Spring Security - Fatal编程技术网

如何建立Spring Security ContextHolder策略?

如何建立Spring Security ContextHolder策略?,spring,spring-security,Spring,Spring Security,我在我的服务中使用异步方法(Spring3@Asyncannotation)。我有一个问题-生成的线程没有安全上下文。原因是Spring安全默认使用SecurityContextHolder.MODE\u THREADLOCAL策略作为其上下文持有者。但是我需要使用SecurityContextHolder.MODE\u INHERITABLETHREADLOCAL策略。 目前,我在AuthenticationSuccessHandler中设置了策略。但在我看来,这不是一个好的做法 那么如何在上

我在我的服务中使用异步方法(Spring3
@Async
annotation)。我有一个问题-生成的线程没有安全上下文。原因是Spring安全默认使用
SecurityContextHolder.MODE\u THREADLOCAL
策略作为其上下文持有者。但是我需要使用
SecurityContextHolder.MODE\u INHERITABLETHREADLOCAL
策略。 目前,我在AuthenticationSuccessHandler中设置了策略。但在我看来,这不是一个好的做法

那么如何在上下文配置文件中设置它呢?

spring security的版本是3.0.0。

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


如果@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;
}

另一种解决方案,如@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>


像个魔术师一样工作。

通过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);
  }
}

谢谢你关于简单豆的建议。但我找到了更方便的解决方案-我在安全上下文中添加了以下代码:我仍然没有配置此bean的httpRequest.getRemoteUser()。请注意其中的含义:如果使用线程池,还应该使用setTaskDecorator()正如这里所解释的,我认为是非常重要的。@FrancoisMarot谢谢你的线程池提示!它救了我的命。使用
SecurityContextHolder.MODE\u INHERITABLETHREADLOCAL
,我的线程池有时无法获取用户上下文。使用
executor.setTaskDecorator(runnable->new DelegatingSecurityContextRunnable(runnable)),似乎总是这样。注意,对于web应用程序,这是一个错误的问题。使用
模式\u INHERITABLETHREADLOCAL
可能会导致线程池中包含异步任务安全上下文错误的线程。更好的方法是使用一个执行器,在运行任务时委托安全上下文。请参见此处:后期注释:-)与配置类中的某种@PostConstruct相比,在安全性方面使用它是否有优势?我必须看一个示例。Postconstruct不会生成SpringBean,所以我不确定如何生成?我的意思是在@Postconstruct内部调用SecurityContextHolder.setStrategyName();这一切都是静态的,所以我猜它可能也会工作。我必须试一试。在这里的一篇文章中有一个完整的解释,不仅涉及@Async,还涉及任何自定义thread@hitch.united请看另一个答案: