如果原始请求是通过 https 发出的,则 Location-header 中的 http

如果原始请求是通过 https 发出的,则 Location-header 中的 http

我目前正在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

响应标头

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

我和一位开发人员进行了交谈,他告诉我以下几点:

代码中有类似 request.sendRedirect("/portal") 的内容,Tomcat 会完成剩下的工作。

尽管堆栈略有不同,但我能够在测试环境中重现该问题。

我的问题:

  1. 为什么当浏览器最初发出请求时,我会http在 -header 中获得方案?Locationhttps
  2. 这是 Apache mod_rewrite/mod_proxy 还是 nginx 问题?
  3. 这是 Tomcat 的问题吗?

答案1

响应标头中会出现 http,因为到达 Apache 的请求是 HTTP - SSL 已在负载均衡器上被剥离。因此从 Apache 的角度来看,这只是一个 HTTP 请求。

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

ServerName https://www.example.org

在全局或虚拟主机配置中。这将覆盖默认的 http 方案,以便 Apache 将发送您想要的响应。服务器名称提到了这一点。

答案2

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

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

答案3

http://nginx.org/docs/http/ngx_http_proxy_module.html#proxy_redirect

proxy_redirect default;
proxy_redirect http://www.example.org/ https://www.example.org/;

相关内容