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 a
I think your mapping definition is missing a *
:
registry.addMapping("/api/query/**")
Without that extra *
, this configuration is not mapped to the /api/query/1121
request path (but it would work on /api/query/5
).
I was facing the same issue and after setting the maxAge attribute everything started working ok!
@Bean
public WebMvcConfigurer CORSConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
.maxAge(-1) // add maxAge
.allowCredentials(false);
}
};
}
if you check the CrossOrigin annotation it has a default value assigned to that attribute
/**
* <p>By default this is set to {@code 1800} seconds (30 minutes).
*/
long maxAge() default -1;
I faced similar issue. I changed the WebMvcConfigurerAdapter to WebMvcConfigurationSupport and it started working.
In addition to this I also moved the RequestMappingHandlerMapping defined in xml configuration file to java configuration.
I have had the same problem working on a Spring mvc application (not Spring Boot). The only way I could solve the problem was to explicitly add a cors filter to the spring security filter chain:
public class MySecurityInitializer extends AbstractSecurityWebApplicationInitializer {
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
final FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", corsFilter());
corsFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
}
protected CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList(CrossOrigin.DEFAULT_ORIGINS));
config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
config.setAllowedHeaders(Arrays.asList(CrossOrigin.DEFAULT_ALLOWED_HEADERS));
config.setAllowCredentials(CrossOrigin.DEFAULT_ALLOW_CREDENTIALS);
config.setMaxAge(CrossOrigin.DEFAULT_MAX_AGE);
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
Luck!
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.
I've just been having the exact same issue, with none of the solutions in this thread working. I've managed to solve it with the following:
A new configuration bean:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilterConfiguration {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
config.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
A modification to my web.xml to add a new filter for all URLs:
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>corsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Obviously you can modify the cors config accordingly.