2016-10-26 1 views
2

Je veux à chaque fois que je fais une demande via feign client, pour définir un en-tête spécifique avec mon utilisateur authentifié.Comment ajouter un intercepteur de requête à un client feignant?

Ceci est mon filtre à partir de laquelle je reçois l'authentification et mis au contexte de sécurité du printemps:

@EnableEurekaClient 
@SpringBootApplication 
@EnableFeignClients 
public class PerformanceApplication { 
    @Bean 
    public Filter requestDetailsFilter() { 
     return new RequestDetailsFilter(); 
    } 

    public static void main(String[] args) { 
     SpringApplication.run(PerformanceApplication.class, args); 
    } 

    private class RequestDetailsFilter implements Filter { 
     @Override 
     public void init(FilterConfig filterConfig) throws ServletException { 

     } 

     @Override 
     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
      String userName = ((HttpServletRequest)servletRequest).getHeader("Z-User-Details"); 
      String pass = ((HttpServletRequest)servletRequest).getHeader("X-User-Details"); 
      if (pass != null) 
       pass = decrypt(pass); 
      SecurityContext secure = new SecurityContextImpl(); 
      org.springframework.security.core.Authentication token = new UsernamePasswordAuthenticationToken(userName, pass); 
      secure. setAuthentication(token); 
      SecurityContextHolder.setContext(secure); 
      filterChain.doFilter(servletRequest, servletResponse); 
     } 

     @Override 
     public void destroy() { 

     } 
    } 
    private String decrypt(String str) { 
     try { 
      Cipher dcipher = new NullCipher(); 

      // Decode base64 to get bytes 
      byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str); 

      // Decrypt 
      byte[] utf8 = dcipher.doFinal(dec); 

      // Decode using utf-8 
      return new String(utf8, "UTF8"); 
     } catch (javax.crypto.BadPaddingException e) { 
     } catch (IllegalBlockSizeException e) { 
     } catch (UnsupportedEncodingException e) { 
     } catch (java.io.IOException e) { 
     } 
     return null; 
    } 
} 

Ceci est mon client feindre:

@FeignClient("holiday-client") 
public interface EmailClient { 
    @RequestMapping(value = "/api/email/send", method = RequestMethod.POST) 
    void sendEmail(@RequestBody Email email); 
} 

Et ici j'ai un intercepteur de demande :

@Component 
public class FeignRequestInterceptor implements RequestInterceptor { 
    private String headerValue; 

    public FeignRequestInterceptor() { 
    } 

    public FeignRequestInterceptor(String username, String password) { 
     this(username, password, ISO_8859_1); 
    } 

    public FeignRequestInterceptor(String username, String password, Charset charset) { 
     checkNotNull(username, "username"); 
     checkNotNull(password, "password"); 
     this.headerValue = "Basic " + base64encode((username + ":" + password).getBytes(charset)); 
    } 

    private static String base64encode(byte[] bytes) { 
     BASE64Encoder encoder = new BASE64Encoder(); 
     return encoder.encode(bytes); 
    } 

    @Override 
    public void apply(RequestTemplate requestTemplate) { 
     requestTemplate.header("Authorization", headerValue); 
    } 
} 

Je ne sais pas comment configurer intercepteur à mon client et comment se t l'en-tête avec le nom d'utilisateur et mot de passe. Comment puis-je accomplir cela?

Répondre

3

Vous n'avez pas vraiment besoin de votre propre implémentation du FeignRequestInterceptor car il y a déjà BasicAuthRequestInterceptor dans le package feign.auth qui fait exactement la même chose. Cela dit, vous avez pratiquement tout déjà mis en place. Tout ce qu'il reste à faire est de définir le bean basicAuthRequestInterceptor avec un nom d'utilisateur et un mot de passe spécifiques:

@Bean 
public RequestInterceptor basicAuthRequestInterceptor { 
    return new BasicAuthRequestInterceptor("username", "password"); 
}