2016-01-11 6 views
6

目標はRequestInterceptorを使用してセキュリティコンテキストからデータを添付することですが、SecurityContextHolder.getContext().getAuthentication()がnullでないにもかかわらず常にnullを返すという問題(100%は確信しています)。Feign RequestInterceptorを使用してアクセスできないセキュリティコンテキスト

これは、インターセプタが作成され、他のスレッドで実行されているためです。

この問題を解決し、セキュリティコンテキストから実際のデータを取得するにはどうすればよいですか?

マイサービス:

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

    @RequestMapping(value = "/list", method = RequestMethod.GET) 
    DocumentListOperation list(); 
} 

マイ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()); 
    } 
} 

答えて

3

私は、それを把握するために、私はあなたがHystrixRequestContextをinitiliazeする必要があります。まずhere

を見つけた記事のおかげで、管理HystrixRequestContext.initializeContext();

Hystrixの子スレッドに渡す必要のある情報を保存する独自のコンテキストを作成する必要があります。

public class UserHystrixRequestContext { 

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

    private UserHystrixRequestContext() {} 

    public static HystrixRequestVariableDefault<User> getInstance() { 
     return userContextVariable; 
    } 
} 

あなたはだから我々は親のコンテキストに新しいスレッドのコンテキストを設定する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); 
      } 
     } 
    } 
} 

をラップする新しい同時方式を登録する必要があります。ここでは

は一例です。

それが完了したら、あなたがHystrixの子スレッド内で、あなたの新しい定義されたコンテキストにアクセスすることができるはず

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

希望誰かを助けること。

関連する問題