2016-01-11 12 views
6

L'obiettivo è collegare alcuni dati dal contesto di sicurezza utilizzando RequestInterceptor, ma il problema è che la chiamata SecurityContextHolder.getContext().getAuthentication() restituisce sempre null anche se non è nulla (sono sicuro al 100%).Contesto di protezione irraggiungibile tramite Feign RequestInterceptor

Come ho capito è perché l'Interceptor viene creato e viene eseguito in altro thread.

Come posso risolvere questo problema e ottenere dati reali dal contesto di sicurezza?

Il mio servizio:

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

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

mio FeignConfig classe:

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

risposta

3

sono riuscito a capirlo, grazie al articolo che ho trovato here

primo luogo è necessario initiliaze HystrixRequestContext HystrixRequestContext.initializeContext(); .

È necessario creare il proprio contesto in cui verranno memorizzate le informazioni che è necessario passare ai thread figlio Hystrix.

Ecco esempio:

public class UserHystrixRequestContext { 

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

    private UserHystrixRequestContext() {} 

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

Devi registrarti nuova strategia di concorrenza che avrebbe avvolgere interfaccia richiamabile

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

Quindi, prima di chiamare oggetto richiamabile abbiamo impostato contesto del nuovo thread per contesto del genitore.

Dopo fatto ciò si dovrebbe essere in grado di accedere al nuovo contesto definito all'interno Hystrix bambino filettature

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

speranza che aiuterà qualcuno.

Problemi correlati