【发布时间】:2020-09-10 08:34:06
【问题描述】:
我将 Async 与一个通过 Feign 调用远程服务的方法一起使用,并且我需要在请求中附加一个 oauth2 令牌,为此我使用了 RequestInterceptor。
@Bean
public RequestInterceptor requestTokenBearerInterceptor() {
return requestTemplate -> {
Object principal = SecurityContextHolder
.getContext()
.getAuthentication()
.getPrincipal();
if (!principal.equals("anonymousUser")) {
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)
SecurityContextHolder.getContext().getAuthentication().getDetails();
requestTemplate.header("Authorization", "bearer " + details.getTokenValue());
}
};
}
但是当 requestInterceptor 在另一个线程中使用时,我无法访问相同的安全上下文,因此 getAuthentication 返回 null。
我尝试在执行程序配置中修复它,我创建了一个 DelegatingSecurityContextExecutor 包装执行程序和安全上下文。但似乎 bean 是在“主”线程中创建的,并且在执行 RestController 方法时使用的安全上下文不一样,所以 getAuthentication() 仍然返回 null。
@Bean(name = "asyncExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(3);
executor.setMaxPoolSize(3);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("AsynchThread-");
executor.initialize();
Executor wrappedExecutor = new DelegatingSecurityContextExecutor(executor, SecurityContextHolder.getContext());
return wrappedExecutor;
}
如何正确配置执行器?
【问题讨论】:
标签: multithreading spring-boot spring-mvc asynchronous spring-cloud-feign