Spring Global CORS configuration not working but Controller level config does

Adam James picture Adam James · Jun 23, 2016 · Viewed 29.7k times · Source

I am trying to configure CORS globally via WebMvcConfigurerAdapter shown below. To test I am hitting my API endpoint via a small node app I created to emulate an external service. When I try this approach the response does not contain the correct headers and fails with

XMLHttpRequest cannot load http://localhost:8080/api/query/1121. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:333' is therefore not allowed access.

Global Config

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/query/**")
                    .allowedOrigins("*")
                    .allowedHeaders("*")
                    .allowCredentials(true);
        }
}

However when I utilize the @CrossOrigin annotation like so it works just fine responding with the proper headers.

@CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*")
@RestController
@RequestMapping(value = "/api/query", produces = MediaType.APPLICATION_JSON_VALUE)
public class QueryController {
   ......
}

Produces

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:333

What am I missing to make the global config work (followed instructions here https://spring.io/blog/2015/06/08/cors-support-in-spring-framework). I feel like I'm missing something simple since annotating the controller works just fine.

Answer

outdev picture outdev · Jul 3, 2016

In order for the global CORS config to work, the client must add these two headers in the OPTIONS request.

Origin: http://host.com
Access-Control-Request-Method: POST

However the @CrossOrigin annotation requires just the "Origin" header.
Your client probably adds the "Origin" header but is missing the "Access-Control-Request-Method".....thats why it works for you with the @CrossOrigin, but doesn't with the global config.