web-dev-qa-db-fra.com

Comment ajouter un intercepteur de requête à un faux client?

Je veux à chaque fois que je fais une demande via feign client, définir un en-tête spécifique avec mon utilisateur authentifié.

Voici mon filtre à partir duquel j'obtiens l'authentification et la mets au contexte de sécurité de 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;
    }
}

Voici mon faux client:

@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 cet intercepteur pour mon client et comment définir l'en-tête avec le nom d'utilisateur et le mot de passe. Comment puis-je y parvenir?

11
Gustavo

Vous n'avez pas vraiment besoin de votre propre implémentation du FeignRequestInterceptor car il y a déjà BasicAuthRequestInterceptor dans le feign.auth package qui fait exactement la même chose.

Cela dit, vous avez déjà pratiquement tout configuré. Il ne reste plus qu'à 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");
}
13
Aleksandr Erokhin