|
XForwardedFilter
XForwardedFilter is a Java Servlet API port of Apache mod_remoteip to handle x-forwarded-for and x-forwarded-proto http headers
Phase-Implementation, Featured
DescriptionThe XForwardedFilter is a Java Servlet API port of mod_remoteip, this filter replaces the apparent client remote IP address and hostname for the request with the IP address list presented by a proxy or a load balancer via a request headers (e.g. "X-Forwarded-For"). Another feature of this filter is to replace the apparent scheme (http/https) and server port with the scheme presented by a proxy or a load balancer via a request header (e.g. "X-Forwarded-Proto"). Filter ConfigurationNote: In most cases, the XForwardedFilter should precede all the other filter and in particular precede logging, authentication, authorization or remote IP related filters.
Basic configuration to handle x-forwarded-forThe filter will process the x-forwarded-for http header. <web-app ...>
...
<filter>
<filter-name>XForwardedFilter</filter-name>
<filter-class>fr.xebia.servlet.filter.XForwardedFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XForwardedFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
...
</web-app>
Basic configuration to handle x-forwarded-for and x-forwarded-protoThe filter will process x-forwarded-for and x-forwarded-proto http headers. Expected value for x-forwarded-proto https connections is https (case insensitive). <web-app ...>
...
<filter>
<filter-name>XForwardedFilter</filter-name>
<filter-class>fr.xebia.servlet.filter.XForwardedFilter</filter-class>
<init-param>
<param-name>protocolHeader</param-name>
<param-value>x-forwarded-proto</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>XForwardedFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
...
</web-app>Advanced samplesSample with internal proxiesXForwardedFilter configuration: <filter>
<filter-name>XForwardedFilter</filter-name>
<filter-class>fr.xebia.servlet.filter.XForwardedFilter</filter-class>
<init-param>
<param-name>allowedInternalProxies</param-name><param-value>192\.168\.0\.10, 192\.168\.0\.11</param-value>
</init-param>
<init-param>
<param-name>remoteIPHeader</param-name><param-value>x-forwarded-for</param-value>
</init-param>
<init-param>
<param-name>remoteIPProxiesHeader</param-name><param-value>x-forwarded-by</param-value>
</init-param>
<init-param>
<param-name>protocolHeader</param-name><param-value>x-forwarded-proto</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>XForwardedFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>Request values:
Note : x-forwarded-by header is null because only internal proxies as been traversed by the request. x-forwarded-by is null because all the proxies are trusted or internal. Sample with trusted proxiesXForwardedFilter configuration: <filter>
<filter-name>XForwardedFilter</filter-name>
<filter-class>fr.xebia.servlet.filter.XForwardedFilter</filter-class>
<init-param>
<param-name>allowedInternalProxies</param-name><param-value>192\.168\.0\.10, 192\.168\.0\.11</param-value>
</init-param>
<init-param>
<param-name>remoteIPHeader</param-name><param-value>x-forwarded-for</param-value>
</init-param>
<init-param>
<param-name>remoteIPProxiesHeader</param-name><param-value>x-forwarded-by</param-value>
</init-param>
<init-param>
<param-name>trustedProxies</param-name><param-value>proxy1, proxy2</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>XForwardedFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>Request values:
Note : proxy1 and proxy2 are both trusted proxies that come in x-forwarded-for header, they both are migrated in x-forwarded-by header. x-forwarded-by is null because all the proxies are trusted or internal. Sample with internal and trusted proxiesXForwardedFilter configuration: <filter>
<filter-name>XForwardedFilter</filter-name>
<filter-class>fr.xebia.servlet.filter.XForwardedFilter</filter-class>
<init-param>
<param-name>allowedInternalProxies</param-name><param-value>192\.168\.0\.10, 192\.168\.0\.11</param-value>
</init-param>
<init-param>
<param-name>remoteIPHeader</param-name><param-value>x-forwarded-for</param-value>
</init-param>
<init-param>
<param-name>remoteIPProxiesHeader</param-name><param-value>x-forwarded-by</param-value>
</init-param>
<init-param>
<param-name>trustedProxies</param-name><param-value>proxy1, proxy2</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>XForwardedFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>Request values:
Note : proxy1 and proxy2 are both trusted proxies that come in x-forwarded-for header, they both are migrated in x-forwarded-by header. As 192.168.0.10 is an internal proxy, it does not appear in x-forwarded-by. x-forwarded-by is null because all the proxies are trusted or internal. Sample with an untrusted proxyXForwardedFilter configuration: <filter>
<filter-name>XForwardedFilter</filter-name>
<filter-class>fr.xebia.servlet.filter.XForwardedFilter</filter-class>
<init-param>
<param-name>allowedInternalProxies</param-name><param-value>192\.168\.0\.10, 192\.168\.0\.11</param-value>
</init-param>
<init-param>
<param-name>remoteIPHeader</param-name><param-value>x-forwarded-for</param-value>
</init-param>
<init-param>
<param-name>remoteIPProxiesHeader</param-name><param-value>x-forwarded-by</param-value>
</init-param>
<init-param>
<param-name>trustedProxies</param-name><param-value>proxy1, proxy2</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>XForwardedFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>Request values:
Note : x-forwarded-by holds the trusted proxy proxy1. x-forwarded-by holds 140.211.11.130 because untrusted-proxy is not trusted and thus, we can not trust that untrusted-proxy is the actual remote ip. request.remoteAddr is untrusted-proxy that is an IP verified by proxy1. Install / Download
<project ...>
...
<dependencies>
...
<dependency>
<groupId>fr.xebia.web</groupId>
<artifactId>xebia-servlet-extras</artifactId>
<version>1.0.6</version>
</dependency>
...
</dependencies>
...
</project>Implementation DetailsThis filter proceeds as follows: If the incoming request.getRemoteAddr() matches the filter's list of internal proxies :
Regular expression vs. IP address blocks: mod_remoteip allows to use address blocks (e.g. 192.168/16) to configure RemoteIPInternalProxy and RemoteIPTrustedProxy ; as Tomcat doesn't have a library similar to apr_ipsubnet_test, XForwardedFilter uses regular expression to configure allowedInternalProxies and trustedProxies in the same fashion as RequestFilterFilter does. Change Log1.0.6 - 2012/03/30 : response.sendRedirect(location) ignores the overwritten scheme. Fix provided by Marc van Andel. Resources
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Thanks caisd. I understood your problem. I moved all the comments to the defect '(4) XForwardedFilter : request.secure and request.scheme are not forced to "false" and "http" if X-Forwarded-Proto=http'.