Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot RestTemplate Basic Authentication using RestTemplateBuilder

In Spring Boot I'm trying to create a RestTemplate which will use basic authentication using

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    builder.basicAuthorization("username", "password");
    RestTemplate template = builder.build();
    return template;
}

I then inject the RestTemplate in my service class as

@Autowired
private RestTemplate restTemplate;

However, my requests fail with a 401 unauthorized exception:

Caused by: org.springframework.web.client.HttpClientErrorException: 401 Unauthorized

Using another REST Client (Postman) the requests to the same URL succeeds so I assume the basic authentication is not working correctly. From the debug output it looks as if the authentication header is not being set. What will make this work?

like image 670
J Kurz Avatar asked Aug 14 '17 09:08

J Kurz


2 Answers

The problem is that you are using the RestTemplateBuilder in a wrong way. The RestTemplateBuilder is immutable. So when doing builder.basicAuthorization("username", "password") you actually get a new instance, with a BasicAuthorizationInterceptor added and configured, of the RestTemplateBuilder. (this applies to all configuration methods of the RestTemplateBuilder they all create a fresh copied instance).

However your code is discarding that specifically configured instance and you are basically using the non secured default RestTemplateBuilder.

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    builder.basicAuthorization("username", "password");
    RestTemplate template = builder.build();
    return template;
}

This code should be replaced with something like this.

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder.basicAuthorization("username", "password").build();
}

Which will use the specifically configured instance.

like image 160
M. Deinum Avatar answered Sep 21 '22 18:09

M. Deinum


One solution is to create the RestTemplate as follows:

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    RestTemplate template = builder.build();
    template.setMessageConverters(
        Arrays.asList(
            new FormHttpMessageConverter(),
            new StringHttpMessageConverter()
        )
    );
    template.getInterceptors().add(new BasicAuthorizationInterceptor("username", "password"));

    return template;
}
like image 24
J Kurz Avatar answered Sep 19 '22 18:09

J Kurz