Spring框架中的跨域CORS配置详解
什么是跨域CORS
CORS(Cross-Origin Resource Sharing,跨域资源共享)是一种机制,允许在浏览器中向不同源(域名、协议或端口不同)的服务器发起请求。在Web开发中,出于安全考虑,浏览器会实施同源策略(Same-Origin Policy),限制从一个源加载的文档或脚本与另一个源的资源进行交互。CORS机制提供了一种安全的方式来实现跨域访问。
Spring中的CORS配置方法
1. 全局CORS配置
使用WebMvcConfigurer配置
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping(\"/**\") // 允许所有路径
.allowedOrigins(\"*\") // 允许所有来源,生产环境应限制具体域名
.allowedMethods(\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\") // 允许的HTTP方法
.allowedHeaders(\"*\") // 允许所有请求头
.exposedHeaders(\"Authorization\") // 暴露的响应头
.allowCredentials(true) // 允许携带凭证(cookie)
.maxAge(3600); // 预检请求结果缓存时间(秒)
}
}
Spring Boot 2.7+ 方式
从Spring Boot 2.7开始,推荐使用CorsFilter而不是WebMvcConfigurer:
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
// 设置允许的源
config.addAllowedOrigin(\"*\");
// 设置允许的HTTP方法
config.addAllowedMethod(\"*\");
// 设置允许的请求头
config.addAllowedHeader(\"*\");
// 设置允许携带凭证
config.setAllowCredentials(true);
// 设置暴露的响应头
config.addExposedHeader(\"Authorization\");
// 设置预检请求结果缓存时间
config.setMaxAge(3600L);
source.registerCorsConfiguration(\"/**\", config);
return new CorsFilter(source);
}
}
2. 控制器级别CORS配置
使用@CrossOrigin注解可以在控制器类或方法级别配置CORS:
// 控制器类级别配置
@RestController
@RequestMapping(\"/api\")
@CrossOrigin(origins = \"*\", maxAge = 3600)
public class ApiController {
@GetMapping(\"/data\")
public ResponseEntity getData() {
return ResponseEntity.ok(\"Data response\");
}
}
// 方法级别配置
@RestController
@RequestMapping(\"/api\")
public class ApiController {
@GetMapping(\"/data\")
@CrossOrigin(origins = \"http://localhost:3000\",
allowedHeaders = \"*\",
methods = {RequestMethod.GET, RequestMethod.POST})
public ResponseEntity getData() {
return ResponseEntity.ok(\"Data response\");
}
}
3. 基于过滤器的CORS配置
@Component
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
// 设置CORS响应头
response.setHeader(\"Access-Control-Allow-Origin\", \"*\");
response.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, PUT, DELETE, OPTIONS\");
response.setHeader(\"Access-Control-Max-Age\", \"3600\");
response.setHeader(\"Access-Control-Allow-Headers\", \"*\");
response.setHeader(\"Access-Control-Expose-Headers\", \"Authorization\");
response.setHeader(\"Access-Control-Allow-Credentials\", \"true\");
// 处理预检请求
if (\"OPTIONS\".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
filterChain.doFilter(request, response);
}
}
Spring Security环境下的CORS配置
当使用Spring Security时,CORS配置需要与Security配置集成:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 添加CORS配置
.cors().and()
// 禁用CSRF(如果需要)
.csrf().disable()
// 其他安全配置...
.authorizeRequests()
.antMatchers(\"/public/**\").permitAll()
.anyRequest().authenticated();
}
// 注入CORS配置Bean
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList(\"*\"));
configuration.setAllowedMethods(Arrays.asList(\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\"));
configuration.setAllowedHeaders(Arrays.asList(\"*\"));
configuration.setExposedHeaders(Arrays.asList(\"Authorization\"));
configuration.setAllowCredentials(true);
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration(\"/**\", configuration);
return source;
}
}
生产环境CORS最佳实践
-
限制允许的源:不要在生产环境使用
\"*\"通配符,而应该指定具体的前端域名:config.setAllowedOrigins(Arrays.asList(\"https://www.example.com\", \"https://app.example.com\")); -
谨慎使用credentials:如果设置了
allowCredentials = true,allowedOrigins不能使用\"*\"通配符。 -
限制允许的HTTP方法:只允许应用程序需要的HTTP方法,而不是全部:
config.setAllowedMethods(Arrays.asList(\"GET\", \"POST\")); -
限制允许的请求头:只允许必要的请求头,提高安全性。
-
设置适当的maxAge:避免频繁的预检请求,减少服务器负担。
常见问题及解决方案
-
CORS策略阻止了请求
- 检查服务器是否正确设置了
Access-Control-Allow-Origin头 - 确保请求的方法和头在允许列表中
- 检查服务器是否正确设置了
-
预检请求失败
- 确保服务器正确处理了
OPTIONS请求 - 检查是否配置了
maxAge参数
- 确保服务器正确处理了
-
凭证模式的问题
- 当使用
withCredentials: true时,服务端必须指定明确的Access-Control-Allow-Origin值 - 不能使用通配符
*
- 当使用
通过以上配置方法,可以根据项目需求灵活地实现Spring应用中的CORS支持,确保前端应用能够安全地进行跨域资源访问。



还没有评论呢,快来抢沙发~