Handling X-FORWARDED-PROTO header in Java web appl

2020-05-19 07:50发布

问题:

Can any one guide me in working with X-FORWARDED-PROTO header in Java web application deployed to Apache Tomcat.

The application setup is in such a way that tomcat talks with Apache webserver, which in turn talks with Cisco Load Balancer, finally the balancer publishes the pages to the client (tomcat -> apache2 -> load balancer -> client).

The SSL Certificate is installed in Load Balancer and it's handling HTTPS requests. My requirement is to make the application behave in such a way that it uses the X-FORWARDED-PROTO and change the pages as HTTP or HTTPS.

Checking on the header files of my webpages I could not find the X-FORWARDED-PROTO header. I don't have access to the Load Balancer configuration either, and the IT has suggested us to use the X-FORWARDED-PROTO to differentiate between HTTP and HTTPS request.

Is there any configuration to be done in Tomcat or Apache level so that it will return the X-FORWARDED-PROTO header? Or is it that the configuration should be handled in Load Balancer?

回答1:

I am pretty sure you have it all figured out by now but I will add the answer nonetheless.

You can use the class org.apache.catalina.valves.RemoteIpValve in the engine tag in conf/server.xml of tomcat.

    <Valve className="org.apache.catalina.valves.RemoteIpValve"
           internalProxies="192.168.1.XXX"
           remoteIpHeader="x-forwarded-for"
           remoteIpProxiesHeader="x-forwarded-by"
           protocolHeader="x-forwarded-proto"
    />

Something to note that is very important is to set the internalProxies value. If this is not set and you are you using a non-standard network setup it could cause some issues where tomcat will not check for x-forwarded headers and it will default to "http". For security reasons I'd recommend to set it even if it works with the defaults.

Look here for more information.



回答2:

Add this to your apache vhost managing connections

<VirtualHost *:80>
  ...
  RewriteEngine On
  RewriteCond %{HTTP:X-Forwarded-Proto} !https
  RewriteRule !/status https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
</VirtualHost>

this assumes your health check is /status, which doesn’t require https