sshjax-rscxfcxf-client

How to set the Host header in JAX-RS / Apache CXF


I am trying to access a service over HTTPS but due to restrictive network settings I am trying to make the request through an ssh tunnel.

I create the tunnel with a command like:

ssh -L 9443:my-service.com:443 sdt-jump-server

The service is only available via HTTPS, its hosted with a self-signed certificate, and it is behind a load-balancer that uses either the hostname or an explicit Host header to route incoming requests to the appropriate backend service.

I am able to invoke the endpoint from my local system using curl like

curl -k -H 'Host: my-service.com' https://localhost:9443/path

However, when I try to use the CXF 3.1.4 implementation of JAX-RS to make the very same request, I can't seem to make it work. I configured a hostnameVerifier to allow the connection, downloaded the server's certificate, and added it to my truststore. Now I can connect, but it seemed like the load-balancer was not honoring the Host header that I'm trying to set.

I was lost for a bit until I set -Djavax.net.debug and saw that the Host header being passed was actually localhost and not the value I set. How to make CXF honor the Host header I'm setting instead of using the value from the URL of the WebTarget?!


Solution

  • CXF uses HttpUrlConnection, so you need to set a system property programmatically

    System.setProperty("sun.net.http.allowRestrictedHeaders", "true")
    

    or at startup:

    -Dsun.net.http.allowRestrictedHeaders=true
    

    See also How to overwrite http-header "Host" in a HttpURLConnection?