使用 Spring Boot 和 Zuul 进行 CORS 预检请求的 Host vs Origin 标头

Posted

技术标签:

【中文标题】使用 Spring Boot 和 Zuul 进行 CORS 预检请求的 Host vs Origin 标头【英文标题】:Host vs Origin header for CORS preflight request with Spring Boot & Zuul 【发布时间】:2017-07-06 15:19:12 【问题描述】:

我将 Zuul 与 Spring Cloud Camden SR5Spring Boot 1.4.4.RELEASE 一起使用

我的前端是React.js 应用程序,由Node Express 服务器提供服务。我的 API 落后于 zuul。

可以通过https://test.mydomain.com 访问前端,通过https://api-test.mydomain.com 访问API (Zuul)

Zuul 中,我确实有一个CORS 过滤器来设置CORS 标头(正确吗?):

if(corsAllowedOrigin.contains(host))
        log.debug(" is allowed", origin);
        response.setHeader("Access-Control-Allow-Origin", origin);
    
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", allowHeaders);
response.setHeader("Access-Control-Expose-Headers", exposeHeaders);
chain.doFilter(req, res);

在 React.js 中,我使用 Fetch 对 API 进行 HTTP 调用。

在每个GETPOST 请求之前,浏览器都会使用以下标头执行OPTIONS 请求:

主机:api-test.mydomain.com 来源:https://test.mydomain.com

当我使用 Spring Cloud Brixton.SR6Spring Boot 1.3.4.RELEASE 时效果很好。

现在我收到了403,错误消息是Invalid CORS request

使用 REST 客户端时,我注意到如果我将标题更改为 Host == Origin,那么我将得到一个 200 OK

CORSspec我可以找到:

除了检查 Origin 标头外,强烈建议资源作者也检查 Host 标头。也就是说,确保该标头提供的主机名与资源所在服务器的主机名匹配。这将提供针对 DNS 重新绑定攻击的保护。

这就是我现在收到403 的原因吗?我怎样才能让我的 API 在不同的主机上运行而不会失败 OPTIONS 请求?

更新

如果我将 CORS 过滤器添加到边缘服务后面的每个单独的服务中,我似乎可以解决这个问题。也就是说,如果我确保每个服务都填充了 Access-Control-Allow-Origin 标头。

在更新之前,我的边缘服务 (Zuul) 上只有一个 CORS 过滤器,我认为这是要走的路。如果我需要为每个服务配置 CORS,这肯定会很浪费吗?这是要走的路吗?

【问题讨论】:

【参考方案1】:

由于某种原因,如果我使用 Spring (org.springframework.web.filter.CorsFilter.CorsFilter) 提供的 CORS 过滤器,它似乎可以工作:

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

【讨论】:

以上是关于使用 Spring Boot 和 Zuul 进行 CORS 预检请求的 Host vs Origin 标头的主要内容,如果未能解决你的问题,请参考以下文章

Dockerized Spring boot 和 Zuul

使用 Spring boot、Eureka、Zuul、Spring Oauth 创建 OAuth 安全微服务的问题

使用带有spring boot和eureka的@EnableZuulProxy闪烁Zuul TimeoutExceptions

Spring Boot Zuul - Hystrix 短路是 OPEN

Spring Boot + 云 | Zuul 代理 | 404 错误

Spring Boot 2.4.2 网关 API 与 Zuul