使用Feign RequestInterceptor的无法访问的安全上下文 [英] Unreachable security context using Feign RequestInterceptor

查看:1284
本文介绍了使用Feign RequestInterceptor的无法访问的安全上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标是使用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的无法访问的安全上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆