简体   繁体   English

使用 Apache 反向代理和来自上游服务的 304 的 Access-Control-Allow-Origin header 值不正确

[英]Incorrect Access-Control-Allow-Origin header value with Apache reverse proxy and 304 from upstream service

I have a situation that's driving me a little bit crazy.我有一种情况让我有点发疯。 I've inherited some infrastructure that includes an Apache 2.2 reverse proxy and an upstream service in the DMZ that serves up resources through a REST API.我继承了一些基础设施,其中包括 Apache 2.2 反向代理和 DMZ 中的上游服务,该服务通过 REST API 提供资源。

There are two applications on different subdomains that request the same JSON resource via the reverse proxy.不同子域上有两个应用程序通过反向代理请求相同的 JSON 资源。

When application #1 ( https://one.host.com ) requests the resource the request headers look like the following (as per Chrome DevTools) and my resource is returned as expected:当应用程序 #1 ( https://one.host.com ) 请求资源时,请求标头如下所示(根据 Chrome DevTools),并且我的资源按预期返回:

Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: rest.api.com
Origin: https://one.host.com
Referer: https://one.host.com/...
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36

The response headers look like:响应标头如下所示:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Requested-With, Referer, Origin, Content-Type, SOAPAction, Authorization, Accept
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Origin: https://one.host.com
Access-Control-Max-Age: 1000
Cache-Control: max-age=0,must-revalidate
Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 1906
Content-Type: application/json;charset=UTF-8
Date: Tue, 18 Jan 2022 22:32:35 GMT
ETag: 7a58c125
Keep-Alive: timeout=5, max=100
Server
Vary: Origin
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block

If I then request the same resource from application #2 ( https://two.host.com ) I encounter a CORS error and the headers look like this (as per Chrome DevTools):如果我然后从应用程序 #2 请求相同的资源( https://two.host.com )我遇到 CORS 错误和标题看起来像这样(根据 Chrome DevTools)

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: rest.api.com
If-None-Match: 7a58c125
Origin: https://two.host.com
Referer: https://two.host.com...
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36

and response headers:和响应头:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Requested-With, Referer, Origin, Content-Type, SOAPAction, Authorization, Accept
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Origin: https://one.host.com
Access-Control-Max-Age: 1000
Cache-Control: max-age=0,must-revalidate
Content-Encoding: gzip
Content-Length: 1906
Content-Type: application/json;charset=UTF-8
Date: Tue, 18 Jan 2022 22:38:54 GMT
ETag: 7a58c125
Server
Vary: Origin
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block

Notice that the Access-Control-Allow-Origin header in the second set of response headers refers to the wrong host/origin, which leads to the CORS error.请注意,第二组响应标头中的 Access-Control-Allow-Origin header 引用了错误的主机/源,这会导致 CORS 错误。

My Apache reverse proxy sets headers like this:我的 Apache 反向代理设置标题如下:

<IfModule mod_headers.c>
  SetEnvIf Referer "^(?:http:\/\/|https:\/\/)[^\/]+" origin_is=$0
  Header set Access-Control-Allow-Origin %{origin_is}e 
  Header set Access-Control-Allow-Credentials true
  Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, HEAD"
  Header set Access-Control-Allow-Headers "X-Requested-With, Referer, Origin, Content-Type, SOAPAction, Authorization, Accept"
  Header set Access-Control-Max-Age 1000
</IfModule>

When I look at my Apache access logs, I will see either a 200 or 304 for the first request, and always see a 304 for the second request.当我查看我的 Apache 访问日志时,我会看到第一个请求的 200 或 304,并且总是看到第二个请求的 304。 I find it odd that my reverse proxy is returning a 304, yet Chrome DevTools shows a 200 response (I see a 304 in Fiddler for the same request that Chrome shows a 200 for).我发现我的反向代理返回 304 很奇怪,但 Chrome DevTools 显示 200 响应(我在 Fiddler 中看到 304 与 Chrome 显示 200 的相同请求)。 If I clear my cache and make the requests in the reverse order, I encounter the same issue, but in reverse.如果我清除缓存并以相反的顺序发出请求,我会遇到同样的问题,但相反。 I can brute force remove the ETag from the response headers (effectively disabling caching it seems) as a workaround, but this isn't desireable.作为一种解决方法,我可以蛮力从响应标头中删除 ETag(似乎有效地禁用了缓存),但这是不可取的。

I'm wondering what/where the problem may be?我想知道问题可能出在哪里/哪里? Should the upstream service not be responding with a 304 for the second request?上游服务是否应该不响应第二个请求的 304? Is a header not being forwarded from the RP to the upstream service? header 是否没有从 RP 转发到上游服务? Should my RP be stripping the ETag from 304 response?我的 RP 是否应该从 304 响应中删除 ETag?

I figured out what the issue is.我弄清楚了问题所在。 It comes down to using an older version of Apache (v2.4.38) as our reverse proxy which has a bug that results in CORS headers being stripped from 304 responses.它归结为使用旧版本的 Apache (v2.4.38) 作为我们的反向代理,它有一个错误导致 CORS 标头从 304 响应中剥离。 Upgrading to >=2.4.48 should resolve the issue.升级到 >=2.4.48 应该可以解决问题。

Details about the issue can be found at: https://bz.apache.org/bugzilla/show_bug.cgi?id=51223 https://bz.apache.org/bugzilla/show_bug.cgi?id=61820 Details about the issue can be found at: https://bz.apache.org/bugzilla/show_bug.cgi?id=51223 https://bz.apache.org/bugzilla/show_bug.cgi?id=61820

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM