How to deal with multiple ClientHttpRequestInterceptors in Spring 4

Viewed 2132

In RestTemplate, I have configured two ClientHttpRequestInterceptor (one for BasicAuthorization and another for Token based authentication.

From client side how I ask RestTemplate to use the correct ClientHttpRequestInterceptor to execute the API call.

Some API calls require BasicAuthorization to work. (For Ex: if the URL starts with "/admin" require BasicAuthorization, others require Token based Authentication)

How I can achieve this in Spring 4?

1 Answers

You could use two instances of RestTemplate, one for Basic auth and one for Token auth.

@Bean
@Qualifier("authRestTemplate")
public RestTemplate getAuthTemplate{
    // create rest template, add auth interceptor
}

@Bean
@Qualifier("tokenRestTemplate")
public RestTemplate getTokenTemplate{
    // create rest template, add token interceptor
}

Then, when autowiring the RestTemplate, use the desired @Qualifier

@Autowired
@Qualifier("authRestTemplate")
private RestTemplate authTemplate;

@Autowired
@Qualifier("tokenRestTemplate")
private RestTemplate tokenTemplate;

Another option would be adding two ClientHttpRequestInterceptor to the RestTemplate

class BasicAuthInterceptor implements ClientHttpRequestInterceptor {

    private final AuthService authService;

    public BasicAuthHeaderInterceptor(AuthService authService) {
        this.authService = authService;
    }

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        if(isApplicable(request)){
            String token = Base64Utils.encodeToString((authService.getUsername() + ":" + authService.getpassword()).getBytes(Charset.forName("UTF-8")));
            request.getHeaders().add("Authorization", "Basic " + token);
        }
        return execution.execute(request, body);
    }

}

class TokenInterceptor implements ClientHttpRequestInterceptor {

    private final AuthService authService;

    public TokenHeaderInterceptor(AuthService authService) {
        this.authService = authService;
    }

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        if(isApplicable(request)){
            request.getHeaders().add("Authorization", "Bearer " + tokenService.getToken());
        }
        return execution.execute(request, body);
    }

}

Then, add the two interceptors to the RestTemplate

@Bean
public RestTemplate restTemplate(){
    RestTemplate template = new RestTemplate();

    template.getInterceptors().add(new BasicAuthInterceptor(authService));
    template.getInterceptors().add(new TokenInterceptor(authService));

    return template;
}
Related