I\'m trying to make CORS play nicely with Spring Security but it\'s not complying. I made the changes described in this article and changing this line in applicationCo
Since main part of question is about unathorized CORS POST-request to login point I immediately point you to step 2.
But regarding to answers count this is the most relevant question to Spring Security CORS request. So I will describe more elegant solution for configuring CORS with Spring Security. Because except rare situations it is not necessary to create filters/interceptors/… to put anything in response. We will do that declaratively by Spring. Since Spring Framework 4.2 we have CORS-stuff like filter, processor, etc out-of-the-box. And some links to read 1 2.
Let's go:
It can be done in different ways:
as global Spring MVC CORS config (in configuration classes like WebMvcConfigurerAdapter)
...
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
...
}
as separate corsConfigurationSource bean
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.applyPermitDefaultValues();
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
}
as external class (which can be used via constructor or autowired as a component)
// @Component // <- for autowiring
class CorsConfig extends UrlBasedCorsConfigurationSource {
CorsConfig() {
orsConfiguration config = new CorsConfiguration();
config.applyPermitDefaultValues(); // <- frequantly used values
this.registerCorsConfiguration("/**", config);
}
}
We will enable CORS support in Spring Security classes like WebSecurityConfigurerAdapter. Be sure that corsConfigurationSource is accessible for this support.
Else provide it via @Resource autowiring or set explicitly (see in example).
Also we let unauthorized access to some endpoints like login:
...
// @Resource // <- for autowired solution
// CorseConfigurationSource corsConfig;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors();
// or autowiring
// http.cors().configurationSource(corsConfig);
// or direct set
// http.cors().configurationSource(new CorsConfig());
http.authorizeRequests()
.antMatchers("/login").permitAll() // without this line login point will be unaccessible for authorized access
.antMatchers("/*").hasAnyAuthority(Authority.all()); // <- all other security stuff
}
If base config works then we can customize mappings, origins, etc. Even add several configurations for different mappings. For example, I explicitly declare all CORS parameters and let UrlPathHelper to not trim my servlet path:
class RestCorsConfig extends UrlBasedCorsConfigurationSource {
RestCorsConfig() {
this.setCorsConfigurations(Collections.singletonMap("/**", corsConfig()));
this.setAlwaysUseFullPath(true);
}
private static CorsConfiguration corsConfig() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedHeader("*");
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.setMaxAge(3600L);
return config;
}
}
To debug my problem I was tracing org.springframework.web.filter.CorsFilter#doFilterInternal method.
And I saw that CorsConfiguration search returns null because Spring MVC global CORS configuration was unseen by Spring Security.
So I used solution with direct usage of external class:
http.cors().configurationSource(corsConfig);