Home > other >  415 Error when authenticating - Spring boot and RestTemplate
415 Error when authenticating - Spring boot and RestTemplate

Time:02-01

I am working on a third-party REST API and I am going to authenticate with their API by making a POST request to the provided end point. I tested this end point using Postman and it works fine, and now I wanted to do it programmatically.

I am using Spring boot 3.0 for development and RestTemplate as the http client. The code I have implemented is below, it gives me a 415 UNSUPPORTED_MEDIA_TYPE error.

        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==");
        headers.add("Accept", "application/json");
        headers.add("Content-Type","application/x-www-form-urlencoded");

        MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<String, String>();
        requestBody.add("grant_type", "client_credentials");

        HttpEntity formEntity = new HttpEntity<MultiValueMap<String, String>>(requestBody, headers);


        String serverEndPoint = "https://xxxxxxx.xxx/auth/oauth2/xx/token";

        ResponseEntity<String> response = restTemplate.exchange(serverEndPoint, HttpMethod.POST,formEntity, String.class);
        System.out.println(response.getStatusCode().value());

Build RestTemplate

@Bean
public RestTemplate getRestTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
        @Override
        public void handleError(ClientHttpResponse response) throws IOException {
            // don't throw
        }
    });
    return restTemplate;
}

But same logic I have implemented using Jersey http client as mentioned below, it gives me successful response with 200 response code.

    JacksonJsonProvider jacksonJsonProvider = new JacksonJaxbJsonProvider()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    Client client = ClientBuilder.newClient(new ClientConfig(jacksonJsonProvider));
    Form form = new Form();
    form.param("grant_type", "client_credentials");


    String serverEndPoint = "https://xxxxxxx.xxx/auth/oauth2/xx/token";

    Response response = client.target(serverEndPoint)
            .request("application/json")
            .header("Authorization", "Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==")
            .post(Entity.entity(form, APPLICATION_FORM_URLENCODED));

    System.out.println(response.getStatus());

Kindly help me to resolve this since I need to move forward with the RestTemplate client.

cUrl From Postman

curl --location --request POST 'https://xxxxxxxxxxxxx.xxx/auth/oauth2/xx/token' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --header 'Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==' \
    --header 'Cookie: coolie data bla bla' \
    --data-urlencode 'grant_type=client_credentials'

CodePudding user response:

If I inspect what the successful calls (curl and the Jersey HttpClient) send to the server vs what RestTemplate.exchange() sends, the only significant difference is that RestTempate.exchange() appends the charset=utf-8 to the Content-Type header.

I suspect that the sever you are calling is too strict on Content-Type and throws a 415 if it does not match "application/x-www-form-urlencoded" exactly.

To prevent this you need to use RestTempate.postForObject() instead. Try changing your RestTemplate call code as follows:

    String serverEndPoint = "https://httpbin.org/post";
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    HttpEntity<String> entity = new HttpEntity<>("grant_type=client_credentials", headers);
    String result = restTemplate.postForObject( serverEndPoint, entity, String.class);

The MediaType is org.springframework.http.MediaType.

Note that I call httpbin.org in the code fragment. I find it extremely useful in researching an issue like this.

  • Related