
最新Spring Security实战教程(十二)CORS安全配置 - 跨域请求的安全边界设定
我们日常开发中,跨域资源共享(CORS)已成为前端与后端分离架构的必备能力。正确配置CORS是后端安全边界的重要一环。但安全与便利的天平往往难以把握——过于宽松的配置可能导致敏感数据泄露,过于严格的策略又会影响正常业务交互,本文我们继续实战教程讲解CORS安全配置。跨域请求是指浏览器在一个域(Origin A)加载的脚本访问另一个域(Origin B)的资源。为保护用户数据,浏览器默认禁止跨域访问
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏19年编写主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
🌛《开源项目》本专栏主要介绍目前热门的开源项目,带大家快速了解并轻松上手使用
✨《开发技巧》本专栏包含了各种系统的设计原理以及注意事项,并分享一些日常开发的功能小技巧
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
🌞《Spring Security》专栏中我们将逐步深入Spring Security的各个技术细节,带你从入门到精通,全面掌握这一安全技术
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~
最新Spring Security实战教程(十二)CORS安全配置 - 跨域请求的安全边界设定
回顾链接:
最新Spring Security实战教程(一)初识Spring Security安全框架
最新Spring Security实战教程(二)表单登录定制到处理逻辑的深度改造
最新Spring Security实战教程(三)Spring Security 的底层原理解析
最新Spring Security实战教程(四)基于内存的用户认证
最新Spring Security实战教程(五)基于数据库的动态用户认证传统RBAC角色模型实战开发
最新Spring Security实战教程(六)最新Spring Security实战教程(六)基于数据库的ABAC属性权限模型实战开发
最新Spring Security实战教程(七)方法级安全控制@PreAuthorize注解的灵活运用
最新Spring Security实战教程(八)Remember-Me实现原理 - 持久化令牌与安全存储方案
最新Spring Security实战教程(九)前后端分离认证实战 - JWT+SpringSecurity无缝整合
最新Spring Security实战教程(十)权限表达式进阶 - 在SpEL在安全控制中的高阶魔法
最新Spring Security实战教程(十一)CSRF攻防实战 - 从原理到防护的最佳实践
专栏更新完毕后,博主将会上传所有章节代码到CSDN资源免费给大家下载,如你不想等后续章节代码需提前获取,可以私信或留言!
1. 前言
我们日常开发中,跨域资源共享(CORS
)已成为前端与后端分离架构的必备能力。正确配置 CORS
是后端安全边界的重要一环。但安全与便利的天平往往难以把握——过于宽松的配置可能导致敏感数据泄露,过于严格的策略又会影响正常业务交互,本文我们继续Spring Security
实战教程讲解CORS安全配置。
2. 背景与原理概述
跨域请求是指浏览器在一个域(Origin A)加载的脚本访问另一个域(Origin B)的资源。为保护用户数据,浏览器默认禁止跨域访问,除非服务器在响应头中明确允许。CORS
机制通过 Access-Control-Allow-*
系列头部,告诉浏览器何种跨域请求被允许,从而实现安全的跨域通信。
2.1 预检请求全流程
当发起“简单请求”时(如 GET/POST
且只有简单头部),浏览器会直接带上 Cookie
等凭证;对复杂请求(如 PUT/DELETE、携带自定义头部
)则先发起一次 预检(OPTIONS
) 请求,确认服务器同意后才发送实际请求。
2.2 关键响应头说明
Access-Control-Allow-*
响应头主要包括以下几个:
响应头 | 安全意义 | 示例值 |
---|---|---|
Access-Control-Allow-Origin | 允许的源列表 | https://your-domain.com |
Access-Control-Allow-Methods | 允许的HTTP方法 | GET,POST,PUT |
Access-Control-Allow-Headers | 允许的请求头 | Content-Type,Authorization |
Access-Control-Max-Age | 预检结果缓存时间(秒) | 86400 |
3. Spring MVC 中的 CORS 支持
Spring Framework
自 4.2 起在 MVC
层面引入了对 CORS
的原生支持,可通过全局配置或注解方式开启
全局配置(WebMvcConfigurer)
@Configuration
public class CorsGlobalConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**") // 应用到所有 /api 路径
.allowedOrigins("https://your-domain.com") // 允许的源
.allowedMethods("GET","POST","PUT") // 允许的方法
.allowedHeaders("Content-Type","Authorization")
.exposedHeaders("X-Total-Count")
.allowCredentials(true) // 允许携带 Cookie
.maxAge(3600); // 预检结果缓存 1 小时
}
}
注解方式(@CrossOrigin)
@RestController
@RequestMapping("/users")
@CrossOrigin(
origins = "https://your-domain.com",
methods = {RequestMethod.GET,RequestMethod.POST},
allowCredentials = "true",
maxAge = 1800
)
public class UserController {
@GetMapping
public List<User> list() { … }
}
4. Spring Security 安全配置方案
尽管 Spring MVC
已处理了 CORS
,但如果启用了 Spring Security
,必须在 Spring Security
配置中显式开启 CORS
支持,否则安全过滤器会在 MVC 之前拦截预检请求,导致跨域失败
全局安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(cors -> cors
.configurationSource(corsConfigurationSource())
)
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
// 其他安全配置...
return http.build();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("https://your-domain.com"));
config.setAllowedMethods(List.of("GET", "POST"));
config.setAllowedHeaders(List.of("Authorization", "Content-Type"));
config.setExposedHeaders(List.of("X-Custom-Header"));
config.setMaxAge(3600L);
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}
5. 安全强化最佳实践
5.1 动态源配置方案
很多时候我们并不希望相关配置是些死在代码里的,我们可以构建 CorsConfigurationSource
来实现动态源配置方案,这里以读取环境变量举例:
@Bean
CorsConfigurationSource corsConfigurationSource(Environment env) {
CorsConfiguration config = new CorsConfiguration();
// 从环境变量读取允许的源
String allowedOrigins = env.getProperty("cors.allowed.origins", "");
config.setAllowedOrigins(Arrays.asList(allowedOrigins.split(",")));
config.applyPermitDefaultValues();
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
5.2 安全头信息增强
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(withDefaults())
.headers(headers -> headers
.httpStrictTransportSecurity(hsts -> hsts
.includeSubDomains(true)
.preload(true)
.maxAgeInSeconds(63072000)
)
.xssProtection(xss -> xss
.headerValue(XXssProtectionHeaderWriter.HeaderValue.ENABLED_MODE_BLOCK)
)
.contentSecurityPolicy(csp -> csp
.policyDirectives("default-src 'self'")
)
);
return http.build();
}
6. 前后端联合调试方案
假设前端部署在 https://frontend.app
,后端 API 接口在 https://your-domain.com
:
- 后端全局配置(见目录 4. Spring Security 安全配置方案)允许该前端域名。
- 前端请求示例:
// 带凭证的跨域请求
fetch('https://your-domain.com/data', {
method: 'GET',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
})
.then(response => {
console.log('Allowed Headers:',
response.headers.get('Access-Control-Allow-Headers'));
});
先发起
OPTIONS https://your-domain.com/data
,带上Origin: https://frontend.app
。
后端返回:
Access-Control-Allow-Origin: https://frontend.app
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Access-Control-Allow-Headers: Content-Type,Authorization
7. 常见安全隐患与对策
7.1 风险矩阵
错误配置 | 潜在风险 | 解决方案 |
---|---|---|
Access-Control-Allow-Origin: * | 敏感数据泄露 | 动态白名单机制 |
允许全部HTTP方法 | 未授权操作风险 | 最小权限原则 |
暴露敏感响应头 | 信息泄露风险 | 严格控制exposedHeaders |
缺失Vary: Origin头 | 缓存投毒攻击 | 自动添加Vary头 |
7.2 生产环境检查清单
- 禁用
allowedOrigins("*")
- 设置合理的
maxAge
值(建议≤1小时) - 严格限制
allowedHeaders
范围 - 启用
allowCredentials
时必须指定具体源 - 结合CSRF保护关键操作
8. 结语
CORS
配置的本质是在便利性与安全性之间寻找平衡点。通过 Spring Security
的精细化配置,我们可以:
- 建立清晰边界:精确控制可交互的客户端范围
- 实施最小授权:按需开放必要的HTTP方法和头部
- 实现动态防御:根据环境变化自动调整安全策略
- 构建纵深防御:与CSRF、CSP等安全机制形成合力
# 生产环境推荐配置示例
cors.allowed.origins=https://web-client.com,https://mobile-client.com
cors.max-age=3600
cors.exposed-headers=X-Request-ID
通过本文内容,相信小伙伴们已经可以在 Spring Boot + Spring Security
项目中,按需灵活地设定跨域安全边界,既满足前后端分离的开发需求,又确保系统不被非授权域滥用。让大家的应用将拥有更健壮的跨域防护能力。
如果你在实践过程中有任何疑问或更好的扩展思路,欢迎在评论区留言,最后希望大家 一键三连 给博主一点点鼓励!
更多推荐
所有评论(0)