Reputation: 135
I have installed Pentaho (9.x) on Tomcat 8.5 and OpenJDK 1.8 as required. In front of it there is Apache 2.4 with mod_proxy_http.
My website is served with HTTPS and I have these Proxy rules:
RequestHeader set X-Forwarded-Proto "https"
ProxyPreserveHost on
ProxyPass "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPassReverse "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPass "/pentaho/" "http://tomcat_host_ip:8080/pentaho/"
ProxyPassReverse "/pentaho/" "http://tomcat_host_ip:8080/pentaho/"
ProxyPass "/pentaho/Login" "http://tomcat_host_ip:8080/pentaho/Login"
ProxyPassReverse "/pentaho/Login" "http://tomcat_host_ip:8080/pentaho/Login"
When I try to log in a get an error during the POST: https://pentaho.mywebsite.org/pentaho/j_spring_security_check
The application try to responde with HTTP protocol instead HTTPS.
In the request header I have the correct Referer and Origin: Origin: https://pentaho.mywebsite.org Referer: https://pentaho.mywebsite.org/pentaho/Login
But the response header reply with HTTP and NOT https: Location http://pentaho.mywebsite.org/pentaho/
Upvotes: 2
Views: 1034
Reputation: 16165
Servlet applications use the scheme
, serverName
and serverPort
properties of a ServletRequest
to generate hyperlinks. Usually Tomcat gets the latter two from the Host
request header, while scheme
depends on the connector.
If you use a reverse proxy, the above logic may not be enough. You have two solution:
scheme
staticallyIn your case the proxy uses HTTPS, while Tomcat uses HTTP, so you must override the scheme
and secure
properties:
<Connector
port="8080"
scheme="https"
secure="true"
...
while the Apache HTTP Server configuration can be shortened to:
ProxyPreserveHost on
ProxyPass "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPassReverse "/pentaho" "http://tomcat_host_ip:8080/pentaho"
Remark that in your answer you didn't set the secure
attribute: this attribute decides whether the transport is confidential. If you don't set it to true, Tomcat will automatically redirect the browser to redirectPort
whenever the application asks for a confidential transport (cf. Securing Web Applications).
This solution only works correctly, if your proxy forwards only HTTPS requests to Tomcat.
scheme
dynamicallyIf you forward both HTTP and HTTPS requests to Tomcat, the server needs a way to distinguish between them. Therefore you need to add a RemoteIpValve
to your Tomcat configuration:
<Valve className="org.apache.catalina.valves.RemoteIpValve" />
<Connector
port="8080"
redirectPort="443"
...
and ask Apache HTTP Server to add an X-Forwarded-Proto
header:
RequestHeader set X-Forwarded-Proto "expr=%{REQUEST_SCHEME}"
ProxyPreserveHost on
ProxyPass "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPassReverse "/pentaho" "http://tomcat_host_ip:8080/pentaho"
This solution has also the advantage to set the client's remoteHost
and remoteAddr
instead of those of the proxy.
Upvotes: 1
Reputation: 135
I solved the problem just adding proxyPort="443" and scheme="https" to my http connector in Tomcat.
The rule
RequestHeader set X-Forwarded-Proto "https"
on Apache was unusefull. This is my correct Apache configuration
ProxyPreserveHost on
ProxyPass "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPassReverse "/pentaho" "http://tomcat_host_ip:8080/pentaho"
ProxyPass "/pentaho/" "http://tomcat_host_ip:8080/pentaho/"
ProxyPassReverse "/pentaho/" "http://tomcat_host_ip:8080/pentaho/"
And this is my Tomcat HTTP connector
<Connector URIEncoding="UTF-8"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
proxyPort="443"
scheme="https"
redirectPort="8443"
relaxedPathChars="[]|"
relaxedQueryChars="^{}[]|&"
maxHttpHeaderSize="65536"
/>
Upvotes: 3