|
对于最新稳定版本,请使用Spring Framework 7.0.1! |
CORS
Spring MVC 允许你处理 CORS(跨原点资源共享)。本节描述了如何实现这一点。
介绍
出于安全考虑,浏览器禁止AJAX调用当前来源以外的资源。例如,你可以把银行账户放在一个标签页,evil.com 在另一个标签页。 脚本 evil.com 不应该能用你的凭证向你的银行 API 发送 AJAX 请求——比如从你的账户中取款!
凭证请求
使用带有凭证请求的 CORS 需要启用允许的资格. 请注意该选项建立了与配置域的高度信任,同时也增加了通过暴露敏感用户特定信息,提高网络应用的攻击表层如 cookie 和 CSRF Tokens。
启用凭证还会影响配置后的CORS万用符处理方式:"*"
-
万能牌不被授权
allowOrigins,但另一种方式 这allowOriginPatterns属性可用于匹配动态的原点集合。 -
启动时
允许的头部或允许方法这访问控制允许头和访问-控制-允许-方法响应头通过复制相关的CORS预检请求中指定的头部和方法来处理。 -
启动时
exposedHeaders,访问控制-暴露-头部响应头被设置为要么设置为配置的头列表,要么设置为万用字符。虽然 CORS 规范不允许在访问-控制-允许-凭证设置为true,大多数浏览器支持,且响应头部在CORS 处理过程中并非全部可用,因此通配符字符即为当指定的头值,无论allowCredentials财产。
| 虽然这种通配卡配置很方便,但建议尽可能配置 而是用有限的数值来提供更高的安全性。 |
加工
CORS规范区分了印前请求、简单请求和实际请求。 想了解CORS的工作原理,你可以阅读这篇文章 还有许多其他,或查看规范以获取更多细节。
春季MVC处理器映射实现为 CORS 提供了内置支持。成功之后
将请求映射到处理器,处理器映射实现检查 CORS 配置以
收到请求并处理后采取进一步行动。会处理检查前请求
直接,简单且实际的CORS请求会被拦截、验证,并且
必须设置 CORS 响应头。
为了启用跨源请求(即起源首部存在,且
与请求的主机不同),你需要有明确声明的 CORS
配置。如果找不到匹配的CORS配置,则会进行检查前检查请求
拒绝。简单和实际的 CORS 请求响应中不会添加 CORS 头部
因此,浏览器会拒绝它们。
每处理器映射可以通过基于URL模式的单独配置CorsConfiguration映射。在大多数情况下,应用
使用 MVC Java 配置或 XML 命名空间来声明此类映射,结果
在一个全局映射中传递给所有处理器映射实例。
你可以在处理器映射与更多人同级
细粒度、处理级别的 CORS 配置。例如,带注释的控制器可以使用
类级或方法级@CrossOrigin注释(其他处理程序可以实现)CorsConfigurationSource).
组合全局配置和局部配置的规则通常是加法的——例如,
全是全球起源,全是本地起源。对于那些只能有一个值的属性
接受,例如:allowCredentials和最大年龄,局部值覆盖全局值。看CorsConfiguration#combine(CorsConfiguration)更多细节请阅读。
|
想了解更多源代码或进行高级定制,请查看背后的代码:
|
@CrossOrigin
这@CrossOrigin注释使得对带注释的控制器方法实现交叉起点请求,
如下示例所示:
-
Java
-
Kotlin
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@GetMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@DeleteMapping("/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
@RestController
@RequestMapping("/account")
class AccountController {
@CrossOrigin
@GetMapping("/{id}")
fun retrieve(@PathVariable id: Long): Account {
// ...
}
@DeleteMapping("/{id}")
fun remove(@PathVariable id: Long) {
// ...
}
}
默认情况下,@CrossOrigin允许:
-
所有起源。
-
所有标题。
-
所有控制器方法映射到的HTTP方法。
allowCredentials默认情况下不启用,因为这会建立信任级别
它暴露了敏感的用户特定信息(如Cookie和CSRFTokens),并且
应仅在适当情况下使用。启用时allowOrigins一定是
设置为一个或多个特定域(但不包括特殊值),或者
这"*"allowOriginPatterns属性可用于匹配动态的原点集合。
最大年龄设置为30分钟。
@CrossOrigin也支持类级,并且所有方法都继承,
如下示例所示:
-
Java
-
Kotlin
@CrossOrigin(origins = "https://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@GetMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@DeleteMapping("/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
@CrossOrigin(origins = ["https://domain2.com"], maxAge = 3600)
@RestController
@RequestMapping("/account")
class AccountController {
@GetMapping("/{id}")
fun retrieve(@PathVariable id: Long): Account {
// ...
}
@DeleteMapping("/{id}")
fun remove(@PathVariable id: Long) {
// ...
}
你可以使用@CrossOrigin无论是在班级还是方法层面,
如下示例所示:
-
Java
-
Kotlin
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin("https://domain2.com")
@GetMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@DeleteMapping("/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
class AccountController {
@CrossOrigin("https://domain2.com")
@GetMapping("/{id}")
fun retrieve(@PathVariable id: Long): Account {
// ...
}
@DeleteMapping("/{id}")
fun remove(@PathVariable id: Long) {
// ...
}
}
全局配置
除了细粒度的控制器方法层级配置外,你可能还想
还定义一些全局CORS配置。你可以设置基于网址的CorsConfiguration任意处理器映射.然而,大多数应用使用以下
MVC Java 配置或 MVC XML 命名空间来实现这一点。
默认情况下,全局配置支持以下功能:
-
所有起源。
-
所有标题。
-
获取,头和发布方法。
allowCredentials默认情况下不启用,因为这会建立信任级别
它暴露了敏感的用户特定信息(如Cookie和CSRFTokens),并且
应仅在适当情况下使用。启用时allowOrigins一定是
设置为一个或多个特定域(但不包括特殊值),或者
这"*"allowOriginPatterns属性可用于匹配动态的原点集合。
最大年龄设置为30分钟。
Java 配置
要在MVC Java配置中启用CORS,你可以使用CorsRegistry回调
如下示例所示:
-
Java
-
Kotlin
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(true).maxAge(3600);
// Add more mappings...
}
}
@Configuration
@EnableWebMvc
class WebConfig : WebMvcConfigurer {
override fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/api/**")
.allowedOrigins("https://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(true).maxAge(3600)
// Add more mappings...
}
}
XML 配置
要在XML命名空间中启用CORS,可以使用<mvc:cors>元素
如下示例所示:
<mvc:cors>
<mvc:mapping path="/api/**"
allowed-origins="https://domain1.com, https://domain2.com"
allowed-methods="GET, PUT"
allowed-headers="header1, header2, header3"
exposed-headers="header1, header2" allow-credentials="true"
max-age="123" />
<mvc:mapping path="/resources/**"
allowed-origins="https://domain1.com" />
</mvc:cors>
CORSFilter
你可以通过内置功能应用CORS支持。CorsFilter.
如果你尝试使用CorsFilter与春季安全一起,请记住Spring
安全性内置支持
科尔斯。 |
要配置过滤器,通过CorsConfigurationSource与其构造器相符,作为
以下示例展示了:
-
Java
-
Kotlin
CorsConfiguration config = new CorsConfiguration();
// Possibly...
// config.applyPermitDefaultValues()
config.setAllowCredentials(true);
config.addAllowedOrigin("https://domain1.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
CorsFilter filter = new CorsFilter(source);
val config = CorsConfiguration()
// Possibly...
// config.applyPermitDefaultValues()
config.allowCredentials = true
config.addAllowedOrigin("https://domain1.com")
config.addAllowedHeader("*")
config.addAllowedMethod("*")
val source = UrlBasedCorsConfigurationSource()
source.registerCorsConfiguration("/**", config)
val filter = CorsFilter(source)