首先,我读过" 如何使用Spring MVC处理HTTP OPTIONS? "但答案似乎并不直接适用于Spring Boot.
看起来我应该这样做:
通过将其设置为
dispatchOptionsRequest来配置dispatcherServlettrue
但是如何做到这一点,因为我没有XML配置,或者DispatcherServlet我的代码中有任何类型的初始化器类(这个答案提到)?
在@RestController类中,我有一个这样的方法,目前不会被调用.
@RequestMapping(value = "/foo", method = RequestMethod.OPTIONS)
public ResponseEntity options(HttpServletResponse response) {
log.info("OPTIONS /foo called");
response.setHeader("Allow", "HEAD,GET,PUT,OPTIONS");
return new ResponseEntity(HttpStatus.OK);
}
Run Code Online (Sandbox Code Playgroud)
Spring Boot 1.2.7.RELEASE; 一个简单的设置与Spring REST指南中的设置没有什么不同 .
在调试CORS问题时,我遇到了我发现了以下行为.Chrome会发出以下OPTIONS预检请求(由Chrome本身在CURL中重写):
curl -v 'https://www.example.com/api/v1/users' -X OPTIONS -H 'Access-Control-Request-Method: POST' -H 'Origin: http://example.com' -H 'Accept-Encoding: gzip,deflate,sdch' -H 'Accept-Language: es-ES,es;q=0.8,en;q=0.6' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36' -H 'Accept: */*' -H 'Referer: http://example.com/users/new' -H 'Connection: keep-alive' -H 'Access-Control-Request-Headers: accept, x-api-key, content-type'
Run Code Online (Sandbox Code Playgroud)
如果以下情况,服务器对此请求的响应:
< HTTP/1.1 403 Forbidden
< Date: Thu, 21 Jul 2016 14:16:56 GMT
* Server Apache/2.4.7 (Ubuntu) is not blacklisted
< Server: Apache/2.4.7 (Ubuntu)
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, …Run Code Online (Sandbox Code Playgroud) 我们在控制器上使用带有@RestController注释的spring mvc,我们正在处理控制器中的授权.我们使用相同的代码来设置响应CORS飞行前请求的允许方法.为实现这一目标,我们有:
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
Run Code Online (Sandbox Code Playgroud)
在调度程序servlet的配置中,然后我们有:
@RequestMapping(value="/some/collections", method=RequestMethod.OPTIONS)
public void collectionOptions(
HttpServletRequest req,
HttpServletResponse res) {
List<RequestMethod> methods = new ArrayList<>();
// check actual permissions, add the appropriate methods
CORS.setAllowedMethodHeaders(res,methods);
}
Run Code Online (Sandbox Code Playgroud)
我们还有一个拦截器,它对CORS pre-flight进行基本检查,以查看原点是否可能具有任何权限.
我们这样做主要是因为某些请求的权限实际上取决于@RequestParams,即:
OPTIONS /api/collections?userId=122
Run Code Online (Sandbox Code Playgroud)
如果您具有管理权限,或者您实际上是具有ID 122的用户,则可能被允许.此外,我们还有API密钥
OPTIONS /api/collections?userId=122&apiKey=ABC
Run Code Online (Sandbox Code Playgroud)
对于一个原点可能没问题,但对另一个原点则不行.
这工作正常,但是现在,Spring 4.2决定是否处理OPTIONS请求,通过调用:
CorsUtils.isCorsRequest(request);
Run Code Online (Sandbox Code Playgroud)
在AbstractHandlerMapping中然后返回
HandlerInterceptor[] interceptors = chain.getInterceptors();
chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors);
Run Code Online (Sandbox Code Playgroud)
而不是HandlerMethod ......
我们需要的是告诉spring让控制器处理OPTIONS请求的一些方法,无论预检请求处理程序是什么.
我们似乎无法找到一个点,我们可以告诉内置的CORS处理是安静的,或者在某个地方配置一些允许我们绕过新添加的代码的子类:
AbstractHandlerMapping.getHandler(HSR request)
Run Code Online (Sandbox Code Playgroud)
这有可能吗?在我主动启用它之前(通过WebMvcConfigurerAdapter或通过@CrossOrigin注释),这样的功能是不是很安静?
--------编辑-------------
HTTP标准说明了以下关于OPTIONS方法的内容:
OPTIONS方法表示请求有关Request-URI标识的请求/响应链上可用的通信选项的信息.该方法允许客户端确定与资源相关联的选项和/或要求,或服务器的能力,而不暗示资源动作或启动资源检索.
认为beyong只是CORS,我认为拦截CORS选项调用虽然相应的方法映射到控制器上是不正确的方法.是的,CORS是你可以用OPTIONS调用做的一件事.但它绝不是唯一的一个.
如果没有映射,并且如果使用不同的请求方法和@CrossOrigin注释映射处理程序方法,我希望触发内置CORS支持的假设会很好,但我不认为任何请求原始标头集应该只自动转到CORS处理程序.