1

This is probably a simple answer, but I can't seem to get it to work. In a cross-domain, preflight AJAX request, the client first makes an OPTIONS request just get a set of headers back to figure out what the remote server accepts.

Right now, for every Spring controller POST interface that I create, I have to also create an OPTIONS interface, like this:

 @RequestMapping(method = RequestMethod.OPTIONS, value = "/addWebService")
    public ResponseEntity addWebServiceOptions() {
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

@RequestMapping(method = RequestMethod.POST, value = "/addWebService")
    public AjaxResponse<WebService> addWebService(Principal principal, @RequestBody WebService webService) throws UserServiceException { ... }

I read somewhere that you can just make one simple method that doesn't have a mapping to a specific path to handle all OPTIONS requests, like this:

@RequestMapping(method = RequestMethod.OPTIONS)
    public ResponseEntity handle() {
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

However, when I add that method, every request I submit states that it can't find a mapping to my requested resource.

Is there a way to handle all OPTIONS requests in a single method without having to create one for every interface I create?

Bal
  • 2,027
  • 4
  • 25
  • 51

1 Answers1

4

For those interested, it was as simple as adding a request mapping of "/*". I can now remove all other OPTIONS methods from my controllers and handle all preflight OPTIONS requests with this single method:

@RequestMapping(method = RequestMethod.OPTIONS, value = "/*")
@ResponseBody
public ResponseEntity handleOptions() {
    return new ResponseEntity(HttpStatus.NO_CONTENT);
}

Also worth noting, I had to add this to my security config to allow all requests to make the OPTIONS call without receiving a 403 error (and to allow websockets to connect properly):

http
        .authorizeRequests()
        .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
        .antMatchers("/stomp/**").permitAll()
        .antMatchers("/**").hasRole("USER");
Bal
  • 2,027
  • 4
  • 25
  • 51
  • 1
    Is this a hack to overcome preflight OPTIONS request? Anyway, it works. – Timuçin Dec 02 '15 at 15:28
  • 1
    No, it's not a hack. The preflight OPTIONS request will always occur by defiition and it is up to you to make sure the response is valid and contains the proper CORS headers. This solution a) allows you to only define one single controller method to define the OPTIONS response for all preflight requests and b) prevents Spring Security from blocking the OPTIONS request. Maybe there is some lower-level way to do this, but this is the simplest way I could find with Spring. – Bal Dec 02 '15 at 17:22