3 CORS支持

3.1 介绍

出于安全考虑,浏览器禁止对当前源之外的资源进行AJAX调用。例如,当你在一个标签页检查你的银行账户时,你可以在另一个标签页打开evil.com的网站。在evil.com中的脚本不能使用你的凭据来通过AJAX请求访问你的银行API(例如,从你的银行取款!)。

跨域资源共享(Cross-origin resource sharing)(CORS)是W3C的标准大部分的浏览器都实现了这个标准来让你可以灵活地指定什么样的跨域请求是被授权的,而不用使用IFRAME或JSONP这些不太安全和功能不强的黑客技术。

从Spring Framework 4.2起,CORS就支持开箱即用。CORS请求(包括一个预检请求OPTIONS方法)自动分发到各个注册的HandlerMapping中。由于CorsProcessor的实现(默认是DefaultCorsProcessor),它们处理CORS预检请求,并拦截CORS的简单而实际请求,以便根据你提供的CORS配置添加相关的CORS响应头(如Access-Control-Allow-Origin)。

由于CORS请求是自动分发的,你不需要改变DispatcherServlet dispatchOptionsRequest的初始参数值;推荐的方式是使用它的默认值(false)。

3.2 控制器方法CORS配置

你可以在你的@RequestMapping注解处理方法上添加一个@CrossOrigin注解来开启CORS。默认@CrossOrigin允许所有的源和在@RequestMapping注解上指定的HTTP方法:

@RestController
@RequestMapping("/account")
public class AccountController { @CrossOrigin
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
} @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}

它也可以在所有的控制器上开启CORS:

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController { @RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
} @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}

在上面的例子中,对retrieve()remove()处理方法都开启了CORS支持,你也可以看到你可以通过@CrossOrigin的属性来配置CORS。

你甚至可以在控制器级别和方法级别进行CORS配置。Spring将组合两个注解的属性来创建一个组合的CORS配置。

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController { @CrossOrigin("http://domain2.com")
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
} @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}

3.3 全局CORS配置

除了基于注解的细粒度配置,你也可能想要定义一些全局的CORS配置。这个与使用过滤器类似,但是可以在Spring MVC中声明跟加上@CrossOrigin的细粒度配置。默认是允许所有的源跟GETHEADPOST方法。

3.3.1 JavaConfig

整个应用开启CORS的例子如下:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer { @Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}

你可以轻松地改变任何属性,也可以将CORS配置指定到特殊的路径模式:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer { @Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(false).maxAge(3600);
}
}

3.3.2 XML命名空间

下面的最小XML配置可以在/**路径模式下开启CORS,具有跟前文提到的JavaConfig一样的缺省属性,例子:

<mvc:cors>
<mvc:mapping path="/**" />
</mvc:cors>

它还可以用定制的属性来指定多个CORS映射:

<mvc:cors>

        <mvc:mapping path="/api/**"
allowed-origins="http://domain1.com, http://domain2.com"
allowed-methods="GET, PUT"
allowed-headers="header1, header2, header3"
exposed-headers="header1, header2" allow-credentials="false"
max-age="123" /> <mvc:mapping path="/resources/**"
allowed-origins="http://domain1.com" /> </mvc:cors>

3.4 高级定制

CorsConfiguration允许你指定CORS请求如何被处理:允许的源,头信息,方法等等。它可以以多种方式提供:

3.5 基于过滤器的CORS支持

为了实现如Spring Security的基于过滤器的安全框架去支持CORS,或其他原生不支持CORS的类库,Spring框架也提供了CorsFilter。而不是使用@CrossOriginWebMvcConfigurer#addCorsMappings(CorsRegistry),你需要注册一个如下的自定义过滤器:

import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter; public class MyCorsFilter extends CorsFilter { public MyCorsFilter() {
super(configurationSource());
} private static UrlBasedCorsConfigurationSource configurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://domain1.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}

你需要确保CorsFilter在其他过滤器之前,相应地看一下关于如何配置Spring Boot的这篇博客


【译者注】

原文:http://docs.spring.io/spring/docs/5.0.0.RC1/spring-framework-reference/web.html#cors

看这篇文章之前,建议看一下阮一峰写的关于CORS的文章

欢迎批评指正

Spring 5.0.0.RC1 - CORS Support 【译文】的更多相关文章

  1. Spring Security 5.0.x 参考手册 【翻译自官方GIT-2018.06.12】

    源码请移步至:https://github.com/aquariuspj/spring-security/tree/translator/docs/manual/src/docs/asciidoc 版 ...

  2. springboot+spring security +oauth2.0 demo搭建(password模式)(认证授权端与资源服务端分离的形式)

    项目security_simple(认证授权项目) 1.新建springboot项目 这儿选择springboot版本我选择的是2.0.6 点击finish后完成项目的创建 2.引入maven依赖  ...

  3. CORS support in Spring Framework--官方

    原文地址:https://spring.io/blog/2015/06/08/cors-support-in-spring-framework For security reasons, browse ...

  4. 时隔3年半Spring.NET 2.0终于正式Release了

    一直很喜欢Spring.NET,不过2011年8月2日1.3.2正式release之后,再没有正式版本的release了. 直到4天前,Spring.NET 2.0 GA终于Release. http ...

  5. 1.Spring Framework 5.0 入门篇

    1.为什么学习Spring? 随着对Java EE的不断接触和理解,你会发现Spring  在各个企业和项目中发挥着越来越重要的作用.掌握Spring 已成为我们IT行业生存必学的本领之一. Spri ...

  6. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.mybatis.spring.mapper.MapperScannerConfigurer#0'

    七月 05, 2018 10:26:54 上午 org.apache.tomcat.util.digester.SetPropertiesRule begin警告: [SetPropertiesRul ...

  7. Quick Guide to Microservices with Spring Boot 2.0, Eureka and Spring Cloud

    https://piotrminkowski.wordpress.com/2018/04/26/quick-guide-to-microservices-with-spring-boot-2-0-eu ...

  8. Spring Boot 2.0 版的开源项目云收藏来了!

    给大家聊一聊云收藏从 Spring Boot 1.0 升级到 2.0 所踩的坑 先给大家晒一下云收藏的几个数据,作为一个 Spring Boot 的开源项目(https://github.com/cl ...

  9. 学习Spring Boot:(二十七)Spring Boot 2.0 中使用 Actuator

    前言 主要是完成微服务的监控,完成监控治理.可以查看微服务间的数据处理和调用,当它们之间出现了异常,就可以快速定位到出现问题的地方. springboot - version: 2.0 正文 依赖 m ...

随机推荐

  1. 读书笔记 effective c++ Item 46 如果想进行类型转换,在模板内部定义非成员函数

    1. 问题的引入——将operator*模板化 Item 24中解释了为什么对于所有参数的隐式类型转换,只有非成员函数是合格的,并且使用了一个为Rational 类创建的operator*函数作为实例 ...

  2. yii框架数据库操作数据访问对象(DAO)简单总结

    Yii提供了强大的数据库编程支持.Yii数据访问对象(DAO)建立在PHP的数据对象(PDO)extension上,使得在一个单一的统一的接口可以访问不同的数据库管理系统(DBMS).使用Yii的DA ...

  3. jQuery使用小结

    $(document).ready( function(){} ); 选择器 $("p:first")            第一个元素 $("p.intro" ...

  4. Java设计模式:桥接模式

    问题提出 生活中有很多事物集合,设为A1,A2......Am ,而每个事物都有功能F1,F2....Fn. 例如邮局的发送业务.简单模拟有两类事物:信件和包裹,均有平邮和挂号邮寄功能.程序设计中如何 ...

  5. dotnetcore中的IOptionsSnapshot<>的自动更新原理

    1.首先讲讲ChangeToken.OnChange方法: 原理是给一个CancellationToken注册一个消费者委托,调用CancellationToken的Cancel的时候会调用这个Can ...

  6. python——面向对象相关

    其他相关 一.isinstance(obj, cls) 检查是否obj是否是类 cls 的对象 1 2 3 4 5 6 class Foo(object):     pass   obj = Foo( ...

  7. IntelliJ-项目配置,解决no artifacts的warnings

    1.名词解释 artifacts:是maven中的一个概念,表示项目/modules如何打包,比如jar,war,war exploded,ear等打包形式, 一个项目或者说module有了artif ...

  8. vsftp使用方法与问题解决

    安装环境 OS:Centos 6.4 vsftp:vsftpd-2.2.2-11.el6_3.1.i686.rpm vsftpd配置文件:/etc/vsftpd/vsftpd.conf 一.      ...

  9. 【BZOJ1001】[BeiJing2006]狼抓兔子

    挺简单一个题,最小割模板 我的感觉就是可能建图的时候会比较麻烦吧,毕竟三个方向. #include <cctype> #include <climits> #include & ...

  10. Visual Lisp获得网络时间的方法

    (defun c:tt (/ ie-obj) (setq ie-obj (vlax-get-or-create-object "Msxml2.xmlhttp")) ) (vlax- ...