当通过 https 发出原始请求时,Location-header 中的 http

pkh*_*mre 7 tomcat nginx https tomcat6 apache-2.2

我目前正在https我们的生产环境中实施,但我在这里为一件小事而挠头。

SSL 在负载均衡器中终止,我们堆栈中的流程基本上是这样的:

生产:浏览器 <- https-> 负载均衡器 <- http-> Apache <- http-> 负载均衡器 <- http-> Tomcat

测试:浏览器 <- https-> nginx <- http-> 负载均衡器 <- http-> Tomcat

当我通过 HTTPS 访问我们的登录页面时:

请求头

POST /login/form HTTP/1.1
Host: www.example.org
Connection: keep-alive
Content-Length: 74
Cache-Control: max-age=0
Origin: https://www.example.org
Content-Type: application/x-www-form-urlencoded
Referer: https://www.example.org/login
Accept-Encoding: gzip,deflate,sdch
Accept-Language: nb,en-US;q=0.8,en;q=0.6
Run Code Online (Sandbox Code Playgroud)

响应头

HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Fri, 17 Jan 2014 11:16:50 GMT
Content-Length: 0
Connection: keep-alive
Set-Cookie: FOO=example
Location: http://www.example.org/portal
Strict-Transport-Security: max-age=31536000
Run Code Online (Sandbox Code Playgroud)

我与一位开发人员交谈,他告诉我以下内容:

在代码中有类似 request.sendRedirect("/portal") 之类的东西,剩下的由 Tomcat 完成。

虽然堆栈有点不同,但我能够在测试环境中重现该问题。

我的问题:

  1. 当来自浏览器的原始请求是用 发出时,为什么我httpLocation-header 中得到了方案https
  2. 这是 Apache mod_rewrite/mod_proxy 还是 nginx 问题?
  3. 这是Tomcat的问题吗?

小智 6

我有一个类似的问题。在您的虚拟主机配置中添加以下内容应该可以解决问题。基本上它会将 http 请求编辑为 https

Header edit Location ^http://(.*)$ https://$1


And*_*man 5

您在响应标头中获得 http,因为到达 Apache 的请求是 HTTP - SSL 已在负载均衡器中被剥离。所以从 Apache 看来,它只是一个 HTTP 请求。

您可以通过设置解决此问题

ServerName https://www.example.org
Run Code Online (Sandbox Code Playgroud)

在全局或虚拟主机配置中。这将覆盖默认的 http 方案,因此 Apache 将发送您想要的响应。ServerName的文档提到了这一点。