Our application runs in a JBoss EAP 6.4. Our development setup provides JBoss instance running in HTTP mode on port 8080 and a reverse proxy with both HTTP (port 9090) and HTTPS (port 9443) endpoints to help test different scenarios.
A problem arises when I try to use "current" URL by injecting the UriInfo
into my request handlers. The scheme part of the URI inside is always dependent on the scheme attribute of the connector setting in the standalone.xml
and not on the actual used scheme. So for example, if I call https://localhost:9443
and http://localhost:9090
when connector's scheme is set to https
, both URLs are converted to HTTPS, i.e. https://localhost:9443
but also https://localhost:9090
. If I switch connector's scheme to http
, both URLs change to HTTP. Needless to say, X-Forwarded-Proto
is also ignored.
Is there a way to make JBoss behave more like most other application servers, i.e. without making any assumptions about used environment and especially reverse proxies and load balancers?
RemoteIpValve should do everything you need.
Source code from the JBossWeb 7.5.20 (EAP 6.4.20): http://anonsvn.jboss.org/repos/jbossweb/tags/JBOSSWEB_7_5_20_FINAL/src/main/java/org/apache/catalina/valves/RemoteIpValve.java
Here's more readable documentation at the upstream Apache Tomcat 7.0 project website: https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html
The minimum config in your case would be the following global valve configuration in the web subsystem:
<valve name="remoteip-valve" module="org.jboss.as.web" class-name="org.apache.catalina.valves.RemoteIpValve">
<param param-name="protocolHeader" param-value="X-Forwarded-Proto"/>
</valve>
This would set the scheme based on the value of the X-Forwarded-Proto header. For https it would also set the secure flag to true and port to 443. Since you seem to require the HTTPS port to be set to 9443, you can do it via additional httpsServerPort parameter (and I think you'll also need to set the httpServerPort to 9090 as you mention above, because the RemoteIpValve would override it to 80 otherwise), e.g.
<valve name="remoteip-valve" module="org.jboss.as.web" class-name="org.apache.catalina.valves.RemoteIpValve">
<param param-name="protocolHeader" param-value="X-Forwarded-Proto"/>
<param param-name="httpServerPort" param-value="9090"/>
<param param-name="httpsServerPort" param-value="9443"/>
</valve>
And you can do more with that valve if you need, just check the documentation for more details.
It's also briefly described for example here (RH login required): https://access.redhat.com/solutions/629863
BTW If you'd be able to use the AJP protocol (from the proxy to the app. server) instead, this wouldn't be needed as AJP is designed for these cases and all the required information should be transferred to the app. server pretty much transparently.