Spring MVC 具有相同路径的两个端点导致 OPTIONS 请求不是 COSR 安全的

Posted

技术标签:

【中文标题】Spring MVC 具有相同路径的两个端点导致 OPTIONS 请求不是 COSR 安全的【英文标题】:Spring MVC two endpoints with the same path cause that OPTIONS request is not COSR safe 【发布时间】:2017-02-15 15:47:10 【问题描述】:

我想阻止我的 REST API 阻止跨域资源共享。不幸的是,我遇到了一些与 Spring MVC 或 Spring Boot 有关的奇怪案例。

为了避免责怪其他库,我使用了干净的 Spring Boot 1.4 并重新创建了问题。

1。只有一个端点 /test

@RestController
@RequestMapping(value = "/test", produces = "application/v1")
public class Endpoint1 

    @RequestMapping(method = RequestMethod.PUT)
    public void put() 
    


Checki preflight cors 请求:

# Request
curl -I -X OPTIONS -H "Access-Control-Request-Method:PUT" -H "Origin:http://evilpage.com" -H "Accept: application/v2" localhost:8080/test

# Response
HTTP/1.1 403
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 20
Date: Thu, 06 Oct 2016 18:38:36 GMT

一切正常 - CORS 请求是不可能的。标头:未显示 Access-Control-Allow-Origin。

2。两个端点 /test,由 Accept 标头进行版本控制

我刚刚添加了带有路径 /test 的第二个端点。

@RestController
@RequestMapping(value = "/test", produces = "application/test2")
public class Endpoint2 

    @RequestMapping(method = RequestMethod.PUT)
    public void put() 
    


再检查一次 OPTIONS 请求将返回什么:

# Request
curl -I -X OPTIONS -H "Access-Control-Request-Method:PUT" -H "Origin:http://evilpage.com" -H "Accept: application/test2" localhost:8080/test

# Response
HTTP/1.1 200
Access-Control-Allow-Origin: http://evilpage.com
Vary: Origin
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Credentials: true
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 0
Date: Thu, 06 Oct 2016 18:40:41 GMT

...和某些东西(Spring boot 或 mvc)设置 Access-Control-Allow-Origin 作为响应!为什么?

效果:浏览器询问我的服务(使用 preflight cors OPTIONS 请求)他是否可以通过源发送 PUT 请求。我的服务重播“没问题”。来自不同来源的 PUT 请求由我的服务处理。

我想知道的:

    这怎么可能?这种机制如何运作? 如何防止我的 API 出现这种行为?

提前感谢您的帮助!

代码:https://github.com/wareq/sof-39903769/tree/master/src/main/java/com/warek - 我只添加了两个具有端点定义的类

【问题讨论】:

【参考方案1】:

我找到了解决方案 - 将过滤器直接注册到 servlet。嗯..也许有更好的解决方案?

@Configuration
public class WebConfig 

    @Bean
    public FilterRegistrationBean corsFilter() 
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin(null);
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    

【讨论】:

以上是关于Spring MVC 具有相同路径的两个端点导致 OPTIONS 请求不是 COSR 安全的的主要内容,如果未能解决你的问题,请参考以下文章

混合 Spring MVC + Spring Data Rest 会导致奇怪的 MVC 响应

Spring Security + MVC:相同的@RequestMapping,不同的@Secured

Spring Web MVC:对请求参数和路径变量使用相同的请求映射

Spring Boot 向 Actuator 端点添加上下文路径

如何拥有两个具有不同命名空间和相同 JAXB 类的不同端点?

提供多个端点的 Cometd 可能不会部署到同一路径 [/cometd]