2016-01-11 6 views
6

Ziel ist es, einige Daten aus dem Sicherheitskontext mit RequestInterceptor anzuhängen, aber das Problem, dass die aufrufende SecurityContextHolder.getContext().getAuthentication() immer null zurückgibt, obwohl sie nicht null ist (100% sicher).Nicht erreichbarer Sicherheitskontext unter Verwendung von Feign RequestInterceptor

Ich verstehe, dass der Interceptor erstellt wird und in anderen Thread ausgeführt wird.

Wie kann ich dieses Problem lösen und tatsächliche Daten aus dem Sicherheitskontext abrufen?

Mein Service:

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

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

Meine FeignConfig Klasse:

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

Antwort

3

ich es geschafft, um es herauszufinden, dank dem Artikel I here gefunden

Zunächst müssen Sie initiliaze HystrixRequestContext HystrixRequestContext.initializeContext(); .

Sie müssen Ihren eigenen Kontext erstellen, in dem Sie Informationen speichern, die Sie an die Hystrix-Kind-Threads weitergeben müssen.

Hier ist Beispiel:

public class UserHystrixRequestContext { 

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

    private UserHystrixRequestContext() {} 

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

Sie müssen neue Concurrency Strategie registrieren, die aufrufbare Schnittstelle

@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); 
      } 
     } 
    } 
} 

Also vor dem Aufruf von Callable Objekt wickeln würden wir neuen Thread Context Eltern Kontext.

Nachdem dies geschehen ist, sollten Sie Ihren neuen definierten Kontext der Lage sein, innerhalb Hystrix Kind den Zugriff auf das Gewinde

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

Hoffnung, dass jemand helfen.