最新Spring Security实战教程(十二)CORS安全配置 - 跨域请求的安全边界设定

article/2025/6/16 12:03:00

在这里插入图片描述

🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏19年编写主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
🌛《开源项目》本专栏主要介绍目前热门的开源项目,带大家快速了解并轻松上手使用
✨《开发技巧》本专栏包含了各种系统的设计原理以及注意事项,并分享一些日常开发的功能小技巧
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
🌞《Spring Security》专栏中我们将逐步深入Spring Security的各个技术细节,带你从入门到精通,全面掌握这一安全技术
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

最新Spring Security实战教程(十二)CORS安全配置 - 跨域请求的安全边界设定

  • 1. 前言
  • 2. 背景与原理概述
    • 2.1 预检请求全流程
    • 2.2 关键响应头说明
  • 3. Spring MVC 中的 CORS 支持
  • 4. Spring Security 安全配置方案
  • 5. 安全强化最佳实践
    • 5.1 动态源配置方案
    • 5.2 安全头信息增强
  • 6. 前后端联合调试方案
  • 7. 常见安全隐患与对策
    • 7.1 风险矩阵
    • 7.2 生产环境检查清单
  • 8. 结语

回顾链接:
最新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 {@Overridepublic 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 {@GetMappingpublic List<User> list() {}
}

4. Spring Security 安全配置方案

尽管 Spring MVC 已处理了 CORS,但如果启用了 Spring Security,必须在 Spring Security 配置中显式开启 CORS 支持,否则安全过滤器会在 MVC 之前拦截预检请求,导致跨域失败

全局安全配置

@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.cors(cors -> cors.configurationSource(corsConfigurationSource())).authorizeHttpRequests(auth -> auth.anyRequest().authenticated())// 其他安全配置...return http.build();}@BeanCorsConfigurationSource 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 生产环境检查清单

  1. 禁用allowedOrigins("*")
  2. 设置合理的maxAge值(建议≤1小时)
  3. 严格限制allowedHeaders范围
  4. 启用allowCredentials时必须指定具体源
  5. 结合CSRF保护关键操作

8. 结语

CORS 配置的本质是在便利性与安全性之间寻找平衡点。通过 Spring Security 的精细化配置,我们可以:

  1. 建立清晰边界:精确控制可交互的客户端范围
  2. 实施最小授权:按需开放必要的HTTP方法和头部
  3. 实现动态防御:根据环境变化自动调整安全策略
  4. 构建纵深防御:与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 项目中,按需灵活地设定跨域安全边界,既满足前后端分离的开发需求,又确保系统不被非授权域滥用。让大家的应用将拥有更健壮的跨域防护能力。

如果你在实践过程中有任何疑问或更好的扩展思路,欢迎在评论区留言,最后希望大家 一键三连 给博主一点点鼓励!


在这里插入图片描述


http://www.hkcw.cn/article/GYgBNnERmb.shtml

相关文章

解决Windows安全中心显示空白页面

1、电脑重装系统后&#xff0c;发现原本一些软件打不开了&#xff0c;电脑莫名认为有病毒&#xff0c;自动删除插件。附图。 2、第一反应是电脑防火墙的原因&#xff0c;默认威胁防护识别到了病毒软件&#xff0c;自动删除。在开始屏幕搜Windows安全中心&#xff0c;打开之后发…

Python全流程开发实战:基于IMAP协议安全下载个人Gmail邮箱内所有PDF附件

文章目录 一、需求分析与安全前置&#xff1a;为什么需要专用工具&#xff1f;1.1 痛点场景1.2 技术方案选择 二、准备工作&#xff1a;Gmail账号安全配置与环境搭建2.1 开启两步验证&#xff08;必做&#xff01;&#xff09;2.2 创建应用专用密码&#xff08;替代普通密码&am…

【网络安全论文】筑牢局域网安全防线:策略、技术与实战分析

【网络安全论文】筑牢局域网安全防线:策略、技术与实战分析 简述一、引言1.1 研究背景1.2 研究目的与意义1.3 国内外研究现状1.4 研究方法与创新点二、局域网网络安全基础理论2.1 局域网概述2.1.1 局域网的定义与特点2.1.2 局域网的常见拓扑结构2.2 网络安全基本概念2.2.1 网络…

评论员点评郑钦文无缘四强 体能优势未转化

北京时间6月3日,在2025年法网女单1/4决赛中,郑钦文以0-2的成绩不敌萨巴伦卡,遗憾未能晋级四强。赛后,资深评论员许旸对比赛进行了点评。许旸表示,这场比赛让人感到不甘心,郑钦文未能将体能优势转化为战斗力。特别是在第二盘,不仅体能没有得到充分利用,技术上的发挥也非…

【吾爱】逆向实战crackme160破解记录(一)

前言 最近想拿吾爱上的crackme程序练练手&#xff0c;发现论坛上已经有pk8900总结好的160个crackme&#xff0c;非常方便&#xff0c;而且有很多厉害的前辈已经写好经验贴和方法了&#xff0c;我这里只是做一下自己练习的记录&#xff0c;欢迎讨论学习&#xff0c;感谢吾爱论坛…

媒体:硬碰硬才是郑钦文的底色 移山之路无悔前行

面对高山,有人绕路,有人架桥,郑钦文选择移山。第八次和萨巴伦卡交手,郑钦文用硬碰硬的方式展示自己强悍的底色。虽然再次失败,依然无怨无悔。这才是郑钦文的网球为人所爱的原因。她的正手轰球已经让高山颤抖。如果郑钦文在第一盘4比2领先时拿下那两次网前机会球,比赛结果…

德国驻华大使馆祝樊振东大展身手 加盟萨尔布吕肯开启新挑战

6月3日,德国驻华大使馆发文祝贺樊振东加盟德国萨尔布吕肯乒乓球俱乐部。奥运冠军、世界冠军樊振东正式成为德国乒乓球甲级联赛(TTBL)俱乐部——萨尔布吕肯1.FC的一员。樊振东表示,他非常期待在萨尔布吕肯和TTBL的全新挑战,渴望成为这家俱乐部的一员,体验新的环境,并与球…

“俄版珍珠港事件”会否引爆核战争 乌无人机袭击引发紧张态势

就在俄乌定于6月2日举行第二轮直接谈判前夕,当地时间6月1日,俄罗斯境内发生了一系列事件。先是桥梁因爆炸坍塌,随后五个空军基地遭遇大规模无人机袭击。乌克兰安全局宣称对此次袭击负责,这是自俄乌冲突爆发以来乌军对俄领土发动的最具渗透性的袭击之一。俄罗斯国防部认定这…

5个月女婴心脏手术后出现脑损伤 家属质疑治疗过程

近日,四川的徐女士反映,她5个多月大的孩子鱼鱼在四川大学华西第二医院锦江院区做完心脏相关手术后,头部莫名出现一个创口。经检查,鱼鱼被诊断为脑出血和脑损伤,后续还伴有癫痫。当地卫健委介入调查后未能得出明确结论。5月29日,记者在事发医院看到,已经一岁多的鱼鱼仍旧…

SpringBoot1--简单体验

1 Helloworld 打开&#xff1a;https://start.spring.io/ 选择maven配置。增加SpringWeb的依赖。 Generate之后解压&#xff0c;代码大致如下&#xff1a; hpDESKTOP-430500P:~/springboot2/demo$ tree ├── HELP.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── s…

乌蛛网行动有多惊艳 无人机开启新战局

乌克兰在大规模使用无人机发动特种攻击方面再次震惊了世界。6月1日,乌克兰国家安全局对俄罗斯境内多地的军用机场发动大规模无人机攻击,声称摧毁了“多达41架战略轰炸机”。俄罗斯方面表示乌军造成的损失没有那么大,但承认了乌军无人机成功袭击的事实。西方媒体称,这种无人…

永辉超市设首席采购官一职 供应链改革加码

6月3日,永辉超市确认佘咸平已就任该公司首席采购官,负责采购和供应链方面的事务。这一任命是永辉超市在供应链改革方面的重要举措。公开资料显示,佘咸平于2002年加入山姆中国采购部,先后担任过山姆北方区采购总监、全国生鲜采购总监等职位。2016年,他加入盒马,担任过盒马…

男子被困河道中间 飞手用无人机救援 2分钟成功营救

男子被困河道中间 飞手用无人机救援 2分钟成功营救!近日,在浙江丽水,一名垂钓爱好者因突降暴雨导致河水暴涨而被困河道中央。当地无人机飞手陈先生迅速出动,仅用2分钟就成功将被困者吊运至安全地带。执行此次救援任务的无人机原本用于农业植保作业,其最大起飞重量符合国家…

外国游客在三亚连救两溺水者 英勇行为获网友点赞

6月2日,一名外国游客在海南三亚勇救两名溺水者的视频引起了广泛关注。许多网友留言表示希望能找到这位救人者,请他吃饭。据视频拍摄者称,2日晚7时20分左右,在三亚椰梦长廊附近海域有人溺水并呼救。他立即拨打了报警电话。这时,一名外国游客毫不犹豫地朝溺水者游去,并成功…

让女童漫展上擦边直播 谁出的馊主意 未成年人保护不容忽视

在广东中山的一场动漫展上,几名衣着暴露的儿童正在进行直播,引起了现场观众的不满。据网传图片显示,两名女童身穿紧身服,脚穿半截丝袜,在一处临时搭建的简易摄影场地前进行表演。主办方工作人员表示,他们已联系家长和摄影工作室,及时制止了这一行为。该事件不仅让现场观…

记者发现成都仍有火车票代售点 引发共鸣与回忆

如今,人们习惯用手机购买火车票,通过12306平台购票已成为常态,甚至不再需要取纸质票或打印电子发票。然而,近日有网友在社交平台上分享了自己在线下火车票代售点成功购票的经历,让人感到意外。这名网友回忆起上次去火车票代售处排队购票的情景,并讲述了自己在成都的一次购…

车企价格战不断 经销商商会“喊话” 抵制内卷竞争

车市价格战再次引发关注,全国工商联汽车经销商商会呼吁停止以“价格战”为主要形式的“内卷式”竞争。近两年,“价格战”成为国内车市的热点话题。数据显示,今年4月,国内乘用车市场均价为17万元,同比下降2.1万元。不仅车价下降,汽车行业利润也受到影响。据统计,今年前四…

端午免签入境外国人增近六成 旅游消费热度不减

端午假期期间,深圳出入境边防检查总站发布的数据显示,内地居民与港澳居民再现来往旅游消费热潮,免签入境外籍旅客数量明显增加。今年端午假期恰逢“六一”国际儿童节和周末,粤港澳三地举办了龙舟赛、美食节、民俗文化展演等文体活动,多地商场推出促销打折活动,吸引大量游…

树莓派PWM控制LED呼吸灯实战

目录 一、什么是PWM二、树莓派引脚图三、命令行控制LED灯四、PWM控制LED呼吸灯五、Python 应用程序控制与驱动程序控制PWM LED灯的对比分析 一、什么是PWM PWM&#xff08;Pulse Width Modulation&#xff0c;脉冲宽度调制&#xff09;是一种通过调节数字信号的占空比&#xf…

手搓GIS引擎:如何用Canvas实现离线地图自由——进击的WebGIS(2)

我用Canvas手搓了一个GIS API&#xff0c;实现离线GeoJSON查看自由。 开篇&#xff1a;当在线地图成为“枷锁” 去年冬天&#xff0c;我在青海无人区做生态调研时&#xff0c;遭遇了职业生涯最尴尬的一幕&#xff1a; “这平板上的地图怎么加载不出来&#xff1f;&#xff01…