Spring Boot RestTemplate Basic Authentication usin

2020-07-10 08:57发布

问题:

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?

回答1:

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.



回答2:

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