I'm using one REST API inside my REST service. Everything works when I call the API from Chrome or Postman, but a Forbbiden response is returned when I call from my application.
PS: I'm using a Java Spring Boot project.
Test Method:
public static void main(String[] args) {
final String uri = "https://swapi.co/api/planets?search=Alderaan";
System.out.println(new RestTemplate().getForObject(uri, String.class));
}
Produces:
20:58:01.436 [main] DEBUG org.springframework.web.client.RestTemplate - HTTP GET swapi.co/api/planets?search=Alderaan
20:58:01.461 [main] DEBUG org.springframework.web.client.RestTemplate - Accept=[text/plain, application/json, application/*+json, */*]
20:58:02.577 [main] DEBUG org.springframework.web.client.RestTemplate - Response 403 FORBIDDEN
Exception in thread "main" org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden
The external API: https://swapi.co/documentation
Everything works when I specify some "user-agent" in the Headers.
It seams to be a restriction on CloudFlare: https://support.cloudflare.com/hc/en-us/articles/200170086-What-does-the-Browser-Integrity-Check-do-
The user-agent of my application is my Java version (Java/1.8.0_151). If you try this user-agent you will receive a restrict access message from CloudFlare.
curl:
curl -H "User-Agent: Java/1.8.0_151" https://swapi.co/api/planets/?search=Alderaan
response: Access denied | swapi.co used Cloudflare to restrict access
This code solve the problem:
HttpHeaders headers = new HttpHeaders();
headers.add("user-agent", "Application");
HttpEntity<String> entity = new HttpEntity<>(headers);
String planetFound = restTemplate.exchange(findPlanetUri, HttpMethod.GET, entity, String.class).getBody();
Another solution:
String planetFound = restTemplate.getForObject(findPlanetUri, String.class);
and
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
ClientHttpRequestInterceptor interceptor = (request, body, execution) -> {
request.getHeaders().add("user-agent", "Application");
return execution.execute(request, body);
};
return restTemplateBuilder.additionalInterceptors(interceptor).build();
}