403 Forbidden: "<HTML><HEAD><EOL><TITLE>Access Denied</TITLE><EOL></HEAD><BODY><EOL><H1>You don't have permission to access

Khanh Luong Van

I'm using Spring and Rest Template to access and get data json from weather.gov:

https://www.weather.gov/documentation/services-web-api

this is my code:

@RequestMapping(value = "/api/v1/forecast", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<ReturnMessage> getForecast(@RequestParam Map<String, Object> params, ModelMap model) {    
    
    final Logger LOGGER = LoggerFactory.getLogger(ForecastController.class);
    
    ReturnMessage message = new ReturnMessage();
    RestTemplate restTemplate = new RestTemplate();     
    
    String url = "https://api.weather.gov/gridpoints/OKX/33,35/forecast";
                                    
    System.out.println("loggg=======");
    LOGGER.info("link part " + url);        
            
    HttpHeaders headers = new HttpHeaders();
    
    headers.add("User-Agent", "myweatherapp.com");
    headers.add("User-Agent", "[email protected]");      
    headers.add(HttpHeaders.ACCEPT, "application/geo+json");     
    
            
    HttpEntity<String> entity = new HttpEntity<String>(jsonObject.toString(), headers);
    String result = restTemplate.postForObject(url, entity, String.class);
    
    System.out.println(result);
    
    return ResponseEntity.ok(message);
}

I have included a User-Agent header in my request but when i send to request to weather.gov to response an exception error:

org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden: "<HTML><HEAD><EOL><TITLE>Access Denied</TITLE><EOL></HEAD><BODY><EOL><H1>Access Denied</H1><EOL> <EOL>You don't have permission to access "http&#58;&#47;&#47;api&#46;weather&#46;gov&#47;gridpoints&#47;OKX&#47;33&#44;35&#47;forecast" on this server.<P><EOL>Reference&#32;&#35;18&#46;177c2117&#46;1685609346&#46;4b1d971<EOL></BODY><EOL></HTML><EOL>"
at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:109) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:183) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:137) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:915) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:864) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:764) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:481) ~[spring-web-6.0.9.jar:6.0.9]
at com.forecast.veriserve.controller.ForecastController.getForecast(ForecastController.java:105) ~[classes/:na]

How to fix the problem ? many thank

xerx593

One problem could be:

User-Agent: (myweatherapp.com, [email protected])

..when reading the "Pricing" and "Authentication" sections.

I could reproduce the issue immediately with HTTP POST! (-> 403), so don't use that (unless API changes).

Here is the working mvc version with comments:

// import java.util.*, org.spr..fr..*
@RestController
static class WeatherController {
    @Autowired
    RestTemplateBuilder rtplB;

    @GetMapping("/forecast")
    public Map getForecast() {
        // customize your api call(+response) from here:
        HttpHeaders headers = new HttpHeaders();
        headers.put("User-Agent",
                List.of(UUID.randomUUID().toString(), // <- until API changes
                        "[email protected]")); // <- *your* contact, if you like
        headers.setAccept(List.of(MediaType.valueOf("application/geo+json")));
        HttpEntity<Void> ent = new HttpEntity<>(headers);
        return rtplB
                .build()
                .exchange(
                        "https://api.weather.gov/gridpoints/OKX/33,35/forecast", // customize, parametrize, call dynamically
                        HttpMethod.GET, // <- POST works not well (->403), didn't try the others..
                        ent, // <- request headers (+ body)
                        Map.class // response type
                        /* , uriVars/... */
                ).getBody(); // <- returning ResponseEntity directly gave "strange" issues, "referencing" the body performs better (in browser).
    }
}

Here the webflux version:

@Autowired
WebClient.Builder wcB;

@GetMapping("/forecast")
public Mono<Map> getForecast(/*...*/) {
    return wcB.build()
            .get()
            .uri("https://api.weather.gov/gridpoints/OKX/33,35/forecast")
            .headers(
                h -> {
                    h.put("User-Agent", List.of(UUID.randomUUID().toString(), "[email protected]"));
                    h.setAccept(List.of(MediaType.valueOf("application/geo+json")));
                }
            )
            .retrieve().bodyToMono(Map.class);
}

BTW

I had the "strange issues" (browser loading behavior) only on the mvc version, when directly returning resttemplate response, a "hold of the body" improves/fixes this. And a minimalist version:

return rtplB.build()
 .getForObject(
   "https://api.weather.gov/gridpoints/OKX/33,35/forecast",
   Map.class
 ); // #

... "seems to work just fine".

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related