目标是使用RequestInterceptor从安全上下文附加一些数据,但问题是,调用SecurityContextHolder.getContext().getAuthentication()始终返回null,即使它不为null(我确定是100%).
The goal is to attach some data from security context using RequestInterceptor, but the problem, that the calling SecurityContextHolder.getContext().getAuthentication() always returns null even though it is not null (I am sure 100%).
据我了解,这是因为拦截器已创建并正在其他线程中运行.
As I understand that's because the Interceptor is created and is being run in other thread.
我该如何解决此问题并从安全上下文中获取实际数据?
How could I solve this problem and get actual data from security context?
我的服务:
@FeignClient(value = "api", configuration = { FeignConfig.class }) public interface DocumentService { @RequestMapping(value = "/list", method = RequestMethod.GET) DocumentListOperation list(); }我的FeignConfig类:
My FeignConfig class:
@Bean public RequestInterceptor requestInterceptor() { return new HeaderInterceptor(userService); } public class HeaderInterceptor implements RequestInterceptor { private UserService userService; public HeaderInterceptor(UserService userService) { this.userService = userService; } @Override public void apply(RequestTemplate requestTemplate) { Authentication a = SecurityContextHolder.getContext().getAuthentication() requestTemplate.header("authentication", a.toString()); } }推荐答案
由于找到了此处
首先,您需要初始化HystrixRequestContext HystrixRequestContext.initializeContext();.
Firstly you need to initiliaze HystrixRequestContext HystrixRequestContext.initializeContext();.
您必须创建自己的上下文,在其中存储需要传递给Hystrix子线程的信息.
You have to create your own Context in which you will store information you need to pass to Hystrix child threads.
以下是示例:
public class UserHystrixRequestContext { private static final HystrixRequestVariableDefault<User> userContextVariable = new HystrixRequestVariableDefault<>(); private UserHystrixRequestContext() {} public static HystrixRequestVariableDefault<User> getInstance() { return userContextVariable; } }您必须注册将包装Callable接口的新并发策略
You have to register new concurrency strategy that would wrap Callable interface
@Component public class CustomHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy { public CustomHystrixConcurrencyStrategy() { HystrixPlugins.getInstance().registerConcurrencyStrategy(this); } @Override public <T> Callable<T> wrapCallable(Callable<T> callable) { return new HystrixContextWrapper<T>(callable); } public static class HystrixContextWrapper<V> implements Callable<V> { private HystrixRequestContext hystrixRequestContext; private Callable<V> delegate; public HystrixContextWrapper(Callable<V> delegate) { this.hystrixRequestContext = HystrixRequestContext.getContextForCurrentThread(); this.delegate = delegate; } @Override public V call() throws Exception { HystrixRequestContext existingState = HystrixRequestContext.getContextForCurrentThread(); try { HystrixRequestContext.setContextOnCurrentThread(this.hystrixRequestContext); return this.delegate.call(); } finally { HystrixRequestContext.setContextOnCurrentThread(existingState); } } } }因此,在调用Callable对象之前,我们将新线程的Context设置为父级的上下文.
So before calling Callable object we set new thread's Context to parent's context.
完成此操作后,您应该能够在Hystrix子线程中访问新定义的上下文
After that is done you should be able to access your new defined context inside Hystrix child threads
User = UserHystrixRequestContext.getInstance().get();
希望对某人有帮助.
更多推荐
使用Feign RequestInterceptor的无法访问的安全上下文
发布评论