Search code examples
springspring-bootresttemplatespring-rest

Spring RestTemplate receives "401 Unauthorized"


I am using the following to retrieve JSON via RestTemplate in Spring 4:

protected DocInfoResponse retrieveData(String urlWithAuth) {
    RestTemplate restTemplate = new RestTemplate();
    HttpHeaders headers = new HttpHeaders();
    headers.add("Authorization", "Basic " + auth.getSig());
    HttpEntity<String> request = new HttpEntity<String>(headers);
    ResponseEntity<DocInfoResponse> response = restTemplate.exchange(urlWithAuth, HttpMethod.GET, request, DocInfoResponse.class);
    return response.getBody();
}

I used the same code (with different response class) to successfully get a JSON doc from the same site (with different parameters to get a different doc).

When I execute the above code I receive the following stack trace (in part):

Caused by: org.springframework.web.client.HttpClientErrorException: 401 Unauthorized 
at 
org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]

Can anyone point me to why this might be receiving the exception?


Solution

  • I found that my issue originally posted above was due to double encryption happening on the auth params. I resolved it by using UriComponentsBuilder and explicitly calling encode() on the the exchange().

    SyncResponse retrieveData(UriComponentsBuilder builder) {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
        HttpEntity<String> request = new HttpEntity<String>(headers);
        ResponseEntity<SyncResponse> response = restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET, request, SyncResponse.class);
        return response.getBody();
    } 
    

    My UriComponentsBuilder was built using:

    UriComponentsBuilder buildUrl(String urlString) {
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(urlString);
    
        return auth.appendAuth(builder);
    }
    

    (The auth.appendAuth() adds additional .queryParams() needed by the target service in urlString.)

    The call to execute this was retrieveData(buildUrl(urlString));.