[GIS] How to configure Geoserver ProxyBaseUrl serving multiple other proxies

geoservergetcapabilitiesPROXY

We have unsecured, internal GeoServers behind an internal load balancer. Access to the load balancer is only available from internal network traffic or an authenticate web proxy. We are able to set the Proxy Base Url setting in GeoServer so that internal traffic can direct to the load balancer.
When we publish our services, we have a single proxy url in the GetCapabilities file which only resolves internally. We do not control the other client applications (OpenLayers, QGIS/ArcMap? etc…) and the proxies that they use to access our services.
Some clients are requesting the GetCapabilities file from GeoServer via their proxy and then attempting to use the proxy base url (sent in the capabilities file) to access map images. This obviously won't work as they are then not directed via their original proxy.

How do we define our base proxy url for services that can be consumed by multiple unknown proxies without exposing our service as an externally resolvable url?
We have a number of approaches in mind, none of which are elegant:

1) Create different GeoServer instances for each proxy

2) Create a GetCapabilities file rewrite at our load balancer / proxy to rewrite the base url depending on the original request origin

3) Expose the service to the internet with basic authentication

Best Answer

Non trivial solution for standalone geoserver

If your reverse proxies set the X-Forwarded-* headers right, you can use the ForwardedHeaderFilter (in Spring Framework since 4.3.0)

Add this to the geoserver web.xml:

<filter>
  <filter-name>ForwardedHeaderFilter</filter-name>
  <filter-class>org.springframework.web.filter.ForwardedHeaderFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>ForwardedHeaderFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

The source code of this filter can be found on github: https://github.com/spring-projects/spring-framework/blob/master/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java

Try to get this compiled against the spring libraries used in your geoserver and put it on the classpath (e.g. as a .jar in webapps/geoserver/WEB-INF/lib).

When running the .war in Tomcat

Then you can just use Tomcat's RemoteIpValve. Put this in your server.xml:

<Valve org.apache.catalina.valves.RemoteIpValve"
       remoteIpHeader="x-forwarded-for"
       protocolHeader="x-forwarded-proto" />
Related Question