# 架构决策:全局 CORS 单一策略 > 日期:2026-08-02 > 决策:仅使用全局 `CorsFilter`;所有 Controller 禁止 `@CrossOrigin` > 本体:`rule:BR-CONFIG-002`、`rule:BR-CONFIG-003` ## 背景 后端已经通过 `CORS_ALLOWED_ORIGINS` 和全局 `CorsFilter` 配置显式 Web Origin,但 17 个 Controller 同时保留了无参数 `@CrossOrigin`。在当前 Filter 顺序下,非白名单请求会先被拒绝;局部注解仍是危险的第二套策略:如果 Filter 注册、请求映射或 Spring 配置方式变化,默认允许全部 Origin 的局部策略可能重新暴露接口。 ## 决策 1. 删除全部 Controller 级 `@CrossOrigin`,不允许页面或接口自行扩展 Origin。 2. 生产 profile 继续要求 `CORS_ALLOWED_ORIGINS` 只含显式 HTTPS origin,禁止通配符、localhost、占位域名、path、query 和 fragment。 3. `CorsBoundaryContractTest` 直接执行真实 `CorsFilter`:非白名单 Origin 在进入 Controller 前返回 403;白名单 Origin 精确回显并允许凭据;预检请求不进入业务代码;源码扫描保证局部注解为 0。 4. `production-smoke.sh` 要求提供一个真实白名单 Origin,同时以固定非白名单 Origin 验证拒绝分支,整个过程只执行 GET/OPTIONS 语义,不写业务数据。 ## 边界 - 微信小程序原生请求不依赖浏览器 CORS,不需要把微信域名加入该白名单。 - Admin 与公开报告 H5 的正式 origin 必须分别列入;API 自身域名不是前端页面 origin 时不自动加入。 - 临时联调域名不得直接写入 Controller;必须通过受控环境配置、评审和生产 preflight。