1. Basic CORS concept
1. What is cross-domain request?
When a browser requests resources from a domain name from a web page, if the domain name, port or protocol is different, a cross-domain request will be generated. For security reasons, browsers will block such requests by default.
2. Simple request vs preflight request
type | condition | How to deal with it |
---|---|---|
Simple request | GET/HEAD/POST method, and Content-Type is text/plain, multipart/form-data or application/x-www-form-urlencoded | Send requests directly with Origin header |
Pre-check request (OPTIONS) | Other requests that do not meet the simple request conditions | Send OPTIONS request first, and then send the actual request after obtaining permission. |
2. 5 ways Spring Boot handles CORS
1. Use @CrossOrigin annotation
Applicable scenarios: CORS configuration for a single controller or method level
@RestController @RequestMapping("/api") public class MyController { // Allow cross-domain access to specific sources @CrossOrigin(origins = "") @GetMapping("/resource") public ResponseEntity<String> getResource() { return ("Cross-domain resources"); } // More detailed configuration @CrossOrigin(origins = {"", ""}, allowedHeaders = {"Content-Type", "Authorization"}, methods = {, }, maxAge = 3600) @PostMapping("/save") public ResponseEntity<String> saveResource() { return ("Save successfully"); } }
2. Global CORS configuration
Applicable scenarios: Application-level unified CORS configuration
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { ("/api/**") // Match path .allowedOrigins("", "") // Allowed sources .allowedMethods("GET", "POST", "PUT", "DELETE") // Allowed methods .allowedHeaders("*") // Allowed request header .exposedHeaders("Authorization", "Content-Disposition") // Exposed response header .allowCredentials(true) // Whether to allow cookies .maxAge(3600); // Preflight request cache time (seconds) // Multiple configurations can be added ("/public/**") .allowedOrigins("*"); } }
3. Use Filter to handle CORS
Applicable scenarios: Needs more underlying control or integration with non-Spring Web environments
@Configuration public class CorsFilterConfig { @Bean public FilterRegistrationBean<CorsFilter> corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); // Configure CORS rules (true); (""); ("*"); ("*"); (3600L); // Effective for all paths ("/**", config); FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source)); (Ordered.HIGHEST_PRECEDENCE); // Set the highest priority return bean; } }
4. CORS configuration in Spring Security
Applicable scenarios: Projects using Spring Security
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { ().and() // Enable CORS support .csrf().disable() // Usually CORS and CSRF cannot be used at the same time .authorizeRequests() .antMatchers("/api/public/**").permitAll() .anyRequest().authenticated(); } // Provide CORS configuration source @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); (("")); (("GET", "POST")); (("*")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); ("/**", configuration); return source; } }
5. Manual setting of response headers
Applicable scenarios: Need to dynamically control the CORS header
@RestController public class DynamicCorsController { @GetMapping("/dynamic-cors") public ResponseEntity<String> dynamicCors(HttpServletRequest request, HttpServletResponse response) { // Dynamically set CORS header according to request String origin = ("Origin"); if (isAllowedOrigin(origin)) { ("Access-Control-Allow-Origin", origin); ("Access-Control-Allow-Credentials", "true"); ("Access-Control-Allow-Methods", "GET, POST"); } return ("Dynamic CORS Response"); } private boolean isAllowedOrigin(String origin) { // Implement your source verification logic return origin != null && (""); } }
3. Detailed explanation of CORS configuration
1. Core response header description
Response header | illustrate |
---|---|
Access-Control-Allow-Origin | The source allowed to access can be a specific domain name or * (* is not recommended, especially when credentials are required) |
Access-Control-Allow-Methods | Allowed HTTP methods (GET, POST, etc.) |
Access-Control-Allow-Headers | Allowed request header |
Access-Control-Expose-Headers | Response headers that can be accessed by the browser |
Access-Control-Allow-Credentials | Whether to allow sending cookies (true/false), Allow-Origin cannot be * when set to true |
Access-Control-Max-Age | Cache time (seconds) of pre-flight request results |
2. Frequently Asked Questions
Question 1: Pre-flight request (OPTIONS) is intercepted
Solution:
- Ensure that OPTIONS requests are not intercepted by security frameworks
- Configure in Spring Security:
().and() .authorizeRequests() .antMatchers(, "/**").permitAll()
Question 2: Request with credentials failed
Solution:
- make sure
allowCredentials(true)
and specificallowedOrigins
(can't be *) - Front-end needs to be set
withCredentials: true
(such as axios)
Question 3: Specific response header cannot be retrieved
Solution:
- use
exposedHeaders
Expose the required head:
.exposedHeaders("Custom-Header", "Authorization")
4. Best Practice Suggestions
- Do not use wildcards in production environment*: explicitly specify the allowed source
- Reasonably restrict HTTP methods: Only open necessary methods (GET/POST, etc.)
- Consider using environment variables: Dynamically configure the allowed sources
@Value("${}") private String[] allowedOrigins; // Use in configuration.allowedOrigins(allowedOrigins)
- Integrate security framework: Spring Security project uses a dedicated CORS configuration
- Test different scenarios: Both simple requests and pre-flight requests need to be tested
5. Complete configuration example
@Configuration @EnableWebMvc public class CorsConfig implements WebMvcConfigurer { @Value("${-origins}") private String[] allowedOrigins; @Override public void addCorsMappings(CorsRegistry registry) { ("/api/**") .allowedOrigins(allowedOrigins) .allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS") .allowedHeaders("*") .exposedHeaders("Authorization", "Content-Disposition") .allowCredentials(true) .maxAge(3600); ("/public/**") .allowedOrigins("*") .allowedMethods("GET", "OPTIONS"); } // Optional: Provide CORS filter as an alternative @Bean public FilterRegistrationBean<CorsFilter> corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); (); (true); ((allowedOrigins)); ("/**", config); FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source)); (Ordered.HIGHEST_PRECEDENCE); return bean; } }
6. Summary
Spring Boot provides a variety of flexible ways to handle CORS:
-
Simple scene:use
@CrossOrigin
annotation -
Unified configuration:accomplish
WebMvcConfigurer
ofaddCorsMappings
method -
Underlying control:Configuration
CorsFilter
-
Safety Projects: Combined with Spring Security
cors()
Configuration - Dynamic requirements: Manually set the response header
Choosing the right approach based on project needs and following security best practices can effectively solve cross-domain problems while ensuring the security of the application.
The above is the detailed content of five ways SpringBoot handles cross-domain requests (CORS). For more information about SpringBoot handles cross-domain requests, please follow my other related articles!