http in the Location-header when the original request was made over https
I am currently implementing https
on our production environment, but I am scratching my head over a little thing here.
SSL is terminated in the load balancer and the flow in our stack is basically like this:
Production: Browser <- https
-> Load balancer <- http
-> Apache <- http
-> Load balancer <- http
-> Tomcat
Testing: Browser <- https
-> nginx <- http
-> Load balancer <- http
-> Tomcat
When I access our login-page over HTTPS:
Request headers
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
Response headers
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
I talked to a developer and he told me the following:
In the code there is sth like request.sendRedirect("/portal") and Tomcat does the rest.
I am able to reproduce the problem on the testing environment, although a bit different stack.
My questions:
- Why do I get
http
as the scheme in theLocation
-header when the original request from the browser was made withhttps
? - Is this an Apache mod_rewrite/mod_proxy or nginx problem?
- Is this a problem with Tomcat?
You get http in the response headers because the request that reaches Apache is HTTP - the SSL has been stripped away at the load balancer. So from what Apache sees, it's just an HTTP request.
You can work around this by setting
ServerName https://www.example.org
in the global or virtual host configuration. This will override the default http scheme so Apache will send the response you want. The documentation for ServerName mentions this.
I had a similar issue. Adding the following in your virtualhost config should solve the problem. Basically it would edit the http request to https
Header edit Location ^http://(.*)$ https://$1