Keywords: Spring Security | CORS Configuration | Cross-Origin Requests | Spring Boot | WebMvcConfigurer
Abstract: This article provides an in-depth analysis of common CORS configuration issues in Spring Security, focusing on the causes of 401 errors and missing Access-Control-Allow-Origin headers. By comparing multiple solutions, it details best practices for correctly configuring CORS in Spring Boot applications, including the use of WebMvcConfigurer's addCorsMappings method. The article explains why certain traditional approaches are no longer suitable in Spring Security 4.1+ and offers complete code examples and configuration guidelines to help developers quickly resolve cross-origin request problems.
Problem Background and Error Analysis
After integrating Spring Security into Spring Boot projects, developers often encounter Cross-Origin Resource Sharing (CORS) related issues. A typical error manifests as: XMLHttpRequest cannot load http://localhost:8080/getKunden. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin http://localhost:3000 is therefore not allowed access. The response had HTTP status code 401. This error indicates that the server response lacks necessary CORS headers, causing browsers to block cross-origin requests.
Limitations of Traditional Configuration Methods
Many developers attempt to solve CORS problems through custom filters, such as creating filters that extend OncePerRequestFilter and manually setting CORS headers in the doFilterInternal method:
@Component
public class MyFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
response.setHeader("Access-Control-Allow-Credentials", "true");
filterChain.doFilter(request, response);
}
}However, this approach often fails in Spring Security environments because the security filter chain may intercept requests before custom filters, particularly when authentication is required, resulting in direct 401 responses without executing the CORS header setting steps.
Official Solution for Spring Security 4.1+
Starting from Spring Security 4.1, the framework provides built-in CORS support. The correct configuration involves enabling CORS in the security configuration class and providing a CorsConfigurationSource Bean:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}Simplified Configuration in Spring Boot
For Spring Boot applications, a more concise solution is to configure CORS mappings directly in the main application class, avoiding complex filter chain configurations:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:3000");
}
};
}
}This configuration leverages Spring MVC's CORS support, registering CORS mappings through the WebMvcConfigurer interface to ensure CORS policies are applied early in the request processing pipeline.
Key Configuration Points
When configuring CORS, several key aspects require attention:
- allowedOrigins: Specifies permitted origins; wildcard
*can be used to allow all origins, but cannot be used with credentials - allowedMethods: Defines allowed HTTP methods, typically including GET, POST, PUT, DELETE, etc.
- allowCredentials: When set to
true, allows credential information (like cookies) to be included - allowedHeaders: Specifies permitted request headers, ensuring inclusion of application-specific custom headers
Common Pitfalls and Avoidance Strategies
Many developers attempt to solve CORS issues through the following approaches, which are no longer recommended in Spring Security 4.1+:
- Using
http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll() - Configuring
web.ignoring().antMatchers(HttpMethod.OPTIONS) - Relying on
@CrossOriginannotations without global CORS configuration
These methods fail to properly handle preflight requests or correctly apply CORS policies within the security filter chain.
Browser Compatibility Considerations
Different browsers implement CORS with variations. Some browsers (like Microsoft Edge) may not fully support wildcard configurations. To ensure cross-browser compatibility, it's recommended to:
- Explicitly specify allowed origins instead of using wildcards
- Provide complete HTTP method lists
- Test across multiple browsers during development
Conclusion
CORS configuration in Spring Security requires balancing security and functionality. By utilizing the native CORS support provided by the Spring framework, developers can avoid the complexities and potential issues associated with custom filters. In Spring Boot environments, the simplest solution involves configuring CORS mappings through WebMvcConfigurer in the application class. This approach is both concise and effective, properly handling preflight requests and correctly applying CORS policies within the security filter chain.