This tutorial discusses how to configure Proxy address forwarding with WildFly’s Web server by setting the attribute proxy-address-forwarding. We will first discuss the basics of this Header attributes and then we will learn the CLI commands to complete the change.
Basics of Proxy Address Forwarding
A common scenario in many architectures is to have WildFly server fronted by a reverse Proxy like Squid or Apache that maps the WildFly domain. You can also use a WildFly server as reverse proxy: the following article shows how to do it: Configuring WildFly as Reverse Proxy
Whatever is your choice, a common issue might happen if you are using for example a navigation rule in your application such as:
<redirect />
Then WildFly redirects from HTTPS back to HTTP causing an error in the request.
Configuring x-forwarded-host on WildFly
The x-forwarded-host
(XFH) header is a de-facto standard HTTP header used primarily in proxying and load balancing scenarios. It identifies the original host requested by the client in the Host
HTTP request header. This is particularly useful when a reverse proxy or load balancer is involved, as it helps the backend server understand the original request context.
Key Points about x-forwarded-Host
:
- Purpose: The
X-Forwarded-Host
header tells the backend server the hostname that the client initially requested. This is crucial when the reverse proxy or load balancer changes the host header to its own hostname. - Usage: When a client makes a request to a server through a reverse proxy, the proxy forwards the request to the backend server. The proxy might modify the
Host
header to its own hostname. TheX-Forwarded-Host
header preserves the original host requested by the client, ensuring that the backend server can handle the request correctly. - Example:
- Client request to proxy:
https://example.com/resource
- Proxy forwards to backend:
https://proxy.com/resource
- Proxy adds
X-Forwarded-Host: example.com
to the request headers
- Client request to proxy:
Let’s see it in practice. We will assume that your configuration already includes a Socket Binding for the https protocol:
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}"> <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/> <socket-binding name="http" port="${jboss.http.port:8080}"/> <socket-binding name="https" port="${jboss.https.port:8443}"/> <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/> <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/> <socket-binding name="txn-recovery-environment" port="4712"/> <socket-binding name="txn-status-manager" port="4713"/> <outbound-socket-binding name="mail-smtp"> <remote-destination host="localhost" port="25"/> </outbound-socket-binding> </socket-binding-group>
If you don’t have it in your configuration, or you want to create another one using a different port, you can still do it as follows:
/socket-binding-group=standard-sockets/socket-binding=proxy-https:add(port=443)
Next, to enable handling of x-forwarded-host
header, you need to set Undertow’s proxy-address-forwarding
attribute to true
. Also, set the redirect-socket
to be the socket binding from our configuration:
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding,value=true) /subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=redirect-socket,value=https)
Here is Undertow’s updated configuration:
<subsystem xmlns="urn:jboss:domain:undertow:10.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}"> <buffer-cache name="default"/> <server name="default-server"> <http-listener name="default" socket-binding="http" redirect-socket="https" proxy-address-forwarding="true" enable-http2="true"/> <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/> <host name="default-host" alias="localhost"> <location name="/" handler="welcome-content"/> <http-invoker security-realm="ApplicationRealm"/> </host> </server> <servlet-container name="default"> <jsp-config/> <websockets/> </servlet-container> <handlers> <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/> </handlers> </subsystem>
Also, make sure the Reverse Proxy is sending in the Header (See for Squid: http://www.squid-cache.org/Versions/v3/3.3/cfgman/request_header_add.html)
X-Forwarded-Proto: https
Finally, another way to get around the problem is using the “secure” attribute in the http listener which causes requests that originate from this listener to be marked as secure, even if the request is not using HTTPS.
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=secure,value=true)
That’s all it takes to configure proxy-address-forwarding on Undertow’s HTTP listener