使用Feign RequestInterceptor无法访问的安全上下文

Dom*_*Mar 6 spring-cloud netflix-feign

目标是使用RequestInterceptor从安全上下文附加一些数据,但问题是,SecurityContextHolder.getContext().getAuthentication()即使调用始终为null ,调用也总是返回null(我肯定是100%).

据我所知,这是因为Interceptor已经创建并正在其他线程中运行.

我怎样才能解决这个问题并从安全上下文中获取实际数据?

我的服务:

@FeignClient(value = "api", configuration = { FeignConfig.class })
public interface DocumentService {

    @RequestMapping(value = "/list", method = RequestMethod.GET)
     DocumentListOperation list();
 }
Run Code Online (Sandbox Code Playgroud)

我的FeignConfig课程:

@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());
    }
}
Run Code Online (Sandbox Code Playgroud)

Dom*_*Mar 5

由于我在这里找到的文章,我设法弄明白了

首先你需要初始化 HystrixRequestContext HystrixRequestContext.initializeContext();

您必须创建自己的上下文,您将在其中存储需要传递给 Hystrix 子线程的信息。

这是示例:

public class UserHystrixRequestContext {

    private static final HystrixRequestVariableDefault<User> userContextVariable = new HystrixRequestVariableDefault<>();

    private UserHystrixRequestContext() {}

    public static HystrixRequestVariableDefault<User> getInstance() {
        return userContextVariable;
    }
}
Run Code Online (Sandbox Code Playgroud)

您必须注册新的并发策略来包装 Callable 接口

@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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以在调用 Callable 对象之前,我们将新线程的上下文设置为父级的上下文。

完成后,您应该能够在 Hystrix 子线程中访问新定义的上下文

User = UserHystrixRequestContext.getInstance().get();

希望这会帮助某人。