原文地址:http://dontpanic.42.nl/2015/04/cors-with-spring-mvc.html

CORS with Spring MVC

 

In this blog post I will explain how to implement Cross-Origin Resource Sharing (CORS) on a Spring MVC backend.

CORS is a W3C spec that allows cross-domain communication from the browser. Whenever a request is made from http://www.domaina.com to http://www.domainb.com, or even from http://localhost:8000 to http://localhost:9000, you will need to implement CORS on your backend.

To allow CORS we need to add the following headers to all Spring MVC responses:


Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: http://localhost:9000 Access-Control-Allow-Methods: GET, OPTIONS, POST, PUT, DELETE Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept Access-Control-Max-Age: 3600

The easiest way to do this is by creating an interceptor:


public class CorsInterceptor extends HandlerInterceptorAdapter { public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials";
public static final String ORIGIN_NAME = "Access-Control-Allow-Origin";
public static final String METHODS_NAME = "Access-Control-Allow-Methods";
public static final String HEADERS_NAME = "Access-Control-Allow-Headers";
public static final String MAX_AGE_NAME = "Access-Control-Max-Age"; @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader(CREDENTIALS_NAME, "true");
response.setHeader(ORIGIN_NAME, "http://localhost:9000");
response.setHeader(METHODS_NAME, "GET, OPTIONS, POST, PUT, DELETE");
response.setHeader(HEADERS_NAME, "Origin, X-Requested-With, Content-Type, Accept");
response.setHeader(MAX_AGE_NAME, "3600");
return true;
} }

Then we register this interceptor in our web configuration:

public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CorsInterceptor());
} ... }

Now all GET requests will be handled correctly.

Modification requests

Whenever we do a modification request (POST, PUT, DELETE), our browser will first send a 'preflight' OPTIONS request. This is an extra security check to see if you can modify data. Because Spring MVC ignores OPTIONS requests by default, we will not get a CORS compliant response. We can overwrite this configuration as follows:

When using a Java configuration, in the DispatcherServletInitializer:


@Override
protected void customizeRegistration(Dynamic registration) {
registration.setInitParameter("dispatchOptionsRequest", "true");
super.customizeRegistration(registration);
}

Or in the web.xml:


<servlet>
<servlet-name>yourServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

Now we can write a simple handler for OPTIONS requests:

@Controller
public class OptionsController { @RequestMapping(method = RequestMethod.OPTIONS)
public ResponseEntity handle() {
return new ResponseEntity(HttpStatus.NO_CONTENT);
} }

This controller handles all OPTIONS requests, sending back a NO_CONTENT response with the desired CORS headers due to our interceptor. Now that OPTIONS respond correctly, the PUT, POST and DELETE will also work correctly.

Congratulations, you now have a CORS compliant Spring MVC backend :)

Multiple origins

Sometimes you have a backend service that is used by multiple applications and thus serves multiple origins. With some minor code changes we can implement this feature:


public class CorsInterceptor extends HandlerInterceptorAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(CorsInterceptor.class); public static final String REQUEST_ORIGIN_NAME = "Origin"; public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials";
public static final String ORIGIN_NAME = "Access-Control-Allow-Origin";
public static final String METHODS_NAME = "Access-Control-Allow-Methods";
public static final String HEADERS_NAME = "Access-Control-Allow-Headers";
public static final String MAX_AGE_NAME = "Access-Control-Max-Age"; private final List<String> origins; public CorsInterceptor(String origins) {
this.origins = Arrays.asList(origins.trim().split("( )*,( )*"));
} @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader(CREDENTIALS_NAME, "true");
response.setHeader(METHODS_NAME, "GET, OPTIONS, POST, PUT, DELETE");
response.setHeader(HEADERS_NAME, "Origin, X-Requested-With, Content-Type, Accept");
response.setHeader(MAX_AGE_NAME, "3600"); String origin = request.getHeader(REQUEST_ORIGIN_NAME);
if (origins.contains(origin)) {
response.setHeader(ORIGIN_NAME, origin);
return true; // Proceed
} else {
LOGGER.warn("Attempted access from non-allowed origin: {}", origin);
// Include an origin to provide a clear browser error
response.setHeader(ORIGIN_NAME, origins.iterator().next());
return false; // No need to find handler
}
} }

All we do now is checking if our request origin is in the list of allowed origins and echo it back into the response. Thus if somebody makes a request from 'domain-a.com' we return back that same 'domain-a.com' as allowed origin, while for 'domain-b.com' we return 'domain-b.com'.

Because the list of allowed origins is provided as string, we can simply define our origins in a properties file:

cors.origins=http://www.domain-a.com,http://www.domain-b.com

CORS with Spring MVC--转的更多相关文章

  1. enable cors in spring mvc with swagger

    a. In controller add @CrossOrigin(origins = "http://localhost:8080") b. In mvc-servlet.xml ...

  2. 从零开始学 Java - Spring MVC 实现跨域资源 CORS 请求

    论职业的重要性 问:为什么所有家长都希望自己的孩子成为公务员? 答:体面.有权.有钱又悠闲. 问:为什么所有家长都希望自己的孩子成为律师或医生? 答:体面.有钱.有技能. 问:为什么所有家长都不怎么知 ...

  3. spring MVC cors跨域实现源码解析

    # spring MVC cors跨域实现源码解析 > 名词解释:跨域资源共享(Cross-Origin Resource Sharing) 简单说就是只要协议.IP.http方法任意一个不同就 ...

  4. Java - Spring MVC 实现跨域资源 CORS 请求

    拦截器设置响应头 这种方式原理就是利用拦截器在方法执行前,我们增加请求的响应头,用来支持跨域请求.这种方案是可行的,大部分都是采用这种方案.我当时也是打算采用这种方案,直到我发现原来 Spring 框 ...

  5. Spring MVC使用Cors实现跨域

    在开发APP过程中,APP调用后端接口有跨域的问题,只要在spring-mvc.xml 文件中加入下面的配置即可: <!-- 解决API接口跨域问题配置 Spring MVC 版本必须是 4.2 ...

  6. Spring MVC 4.2 CORS 跨域访问

    跨站 HTTP 请求(Cross-site HTTP request)是指发起请求的资源所在域不同于该请求所指向资源所在的域的 HTTP 请求.比如说,域名A(http://domaina.examp ...

  7. Spring MVC 实现跨域资源 CORS 请求

    说到 AJAX 跨域,很多人最先想到的是 JSONP.的确,JSONP 我们已经十分熟悉,也使用了多年,从本质上讲,JSONP 的原理是给页面注入一个 <script>,把远程 JavaS ...

  8. Spring MVC配置CORS(解决跨域请求)

    1. CORS 简介 同源策略(same origin policy)是浏览器安全的基石.在同源策略的限制下,非同源的网站之间不能发送 ajax 请求的. 为了解决这个问题,w3c 提出了跨源资源共享 ...

  9. Spring MVC 后端接口支持跨域CORS调用

    Spring MVC 从4.2版本开始增加了对CORS的支持,可以全局配置,也可以对类或方法配置:可以通过Java代码,也可以通过xml配置方式. 对于低版本的Spring MVC 可以通过Filte ...

随机推荐

  1. ActiveMQ服务安装

    1.下载安装ActiveMQ服务提供者 http://activemq.apache.org/ 2.启用ActiveMQ服务 cd [activemq_install_dir] bin\activem ...

  2. 开源 PHP 项目找队友、顾问、指导、贡献者等等

    介绍站点还没做,先直接甩代码链接了 https://github.com/litphp/litphp Lit是什么? Lit是我一直在撸的个人框架,按第一次上传代码来说历史 超过4年 了,从还能支持P ...

  3. Qt之图形(组合)

    简述 使用QPainter绘制图形或者图像时,在重叠区域使用组合模式(Composition_mode).在绘图设备上通过组合模式使用QImage时,必须使用Format_ARGB32_Premult ...

  4. 聊聊高并发(四十四)解析java.util.concurrent各个组件(二十) Executors工厂类

    Executor框架为了更方便使用,提供了Executors这个工厂类.通过一系列的静态工厂方法.能够高速地创建对应的Executor实例. 仅仅有一个nThreads參数的newFixedThrea ...

  5. 删除heroku上的数据库记录

    部署本地项目到heroku上.在线上插入数据到数据库,本地代码再次更新到heroku,线上的数据记录还存在单是图片丢失.问题还没有解决: 本地代码和heroku代码怎样同步? heroku使用的pg和 ...

  6. codevs1052

    题目地址:http://codevs.cn/problem/1053/ 分析: 模拟 代码: var s:string; a:array['a'..'z'] of longint; i,j,t,n:l ...

  7. thinkphp5项目--个人博客(八)

    thinkphp5项目--个人博客(八) 项目地址 fry404006308/personalBlog: personalBloghttps://github.com/fry404006308/per ...

  8. User-defined types

    We have used many of Python’s built-in types; now we are going to define a new type. As an example, ...

  9. OpenGL编程(一)渲染一个指定颜色的背景窗口

    上次已经搭好了OpenGL编程的环境.已经成功运行了第一个程序.可只是照搬书上的代码,并没弄懂其中的原理.这次通过一个小程序来解释使用GLUT库编写OpenGL程序的过程. 程序的入口 与其他程序一样 ...

  10. c# window服务-初学习

    window服务-初学习 一.工具: VS2015+NET Framework4.5. 二.操作: 1.新建windows服务的项目: 2.修改windows服务相关内容: 3.预览windows服务 ...