当原始请求通过https进行时,位置标头中的http

我目前在我们的生产环境中实现了https ,但是我正在为这个小东西挠头。

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

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

testing :浏览器< – https – > nginx < – http – >负载均衡器< – http – > Tomcat

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

请求标头

 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(“/门户”)和其余的Tomcat。

我能够在testing环境中重现问题,虽然有点不同。

我的问题:

  1. 为什么当浏览器的原始请求使用https时,我会在Location header中使用http作为scheme?
  2. 这是一个Apache的mod_rewrite / mod_proxy或Nginx的问题?
  3. 这是Tomcat的问题吗?

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

你可以通过设置来解决这个问题

 ServerName https://www.example.org 

在全局或虚拟主机configuration中。 这将覆盖默认的httpscheme,所以Apache将发送你想要的响应。 ServerName的文档提到了这一点。

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

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

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/;