Adding X-Forwarded-For header to CA Access Gateway (CA Secure Proxy Server)

Document created by Mark.ODonohue Employee on Sep 29, 2014Last modified by kristen.palazzolo on Dec 17, 2016
Version 6Show Document
  • View in full screen mode


This article discusses how to implement the "X-Forwarded-For" header, in CA Secure Proxy Server as a custom SPS Filter, with coded example attached.


1.1 Introduction

The X-Forwarded-For (XFF) HTTP header field is a de facto standard for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer.  However this is not (yet) a built in feature for CA Secure Proxy Server.



There have been a number of requests for it over the last few years, from both customers and CA Services, I always thought it should be possible via an SPS Filter, and should not be too difficult to implement.  So after another request a few weeks ago, I spent a bit of time on the weekend to check that, and this is the result.


Here we show how to implement "X-Forwarded-For" header with the attached (fairly simple) custom java SPS filter.  The attached zip file contains: a prebuilt (JRE 1.6) jar file; samples of the SPS configuration file changes that are needed; as well as the java source code and simple build script.


The SPSForwardedForFilter implements a SPS filter (implementing a "preFilter" method),  the prefilter will looks up the IP address of the client, as identified by apache, and sets it the X-Forwarded-For header before passing the request onto the backend server.

The header then can be used by the backend server to identify the client IP address:




If the X-Forward-For header already exists, then the filter can (optionally) append or overwrite the header.


X-Forwarded-For: clientIP, proxy1IP, proxy2IP,


The choice of overwrite or append will depend on your downstream environment, but you do need to be aware of the clients ability to add thier own initial X-Forwarded-For header in an attempt to spoof the original location.

For more details about X-Forwarded-For header see : X-Forwarded-For - Wikipedia, the free encyclopedia



1.2 Deploying the SPSForwardForFilter.jar file

The SPSForwardForFilter.jar file (compiled version provided in the zip file) needs to be copied into the CLASSPATH's used by the proxy-engine.  The easiest way to do that is to copy it into the Tomcat lib directory.  for example : 

          copy/y SPSForwardForFilter.jar C:\CA\secure-proxy\Tomcat\lib\

          cp SPSForwardForFilter.jar /opt/secure-proxy/Tomcat/lib/


1.3 Changes in Server.conf


Server.conf contains most of the proxy-engine configuration settings including some commented out examples of filters.  Using those, along with the sample provided in the sps-site-specific subdirectory of the zip file, as a guide we define a filter in the Server.conf file named “ForwardedForFilter” as follows:




Since the defaults are likely to be what you want anyway, these settings a commented out by default.

#filter.ForwardedForFilter.init-param.XForwardForHeaderName="X-Forwarded-For" # defaults to this.

#filter.ForwardedForFilter.init-param.mode="Append" # (Append|OverWrite) defaults to Append.

#filter.ForwardedForFilter.init-param.enabled="True" # (True|False) defaults to True.



1.4 Changes in proxyrules.xml

The proxyrules.xml describes which backend server the SPS will forward the request onto, we edit the proxyrules.xml file to add the use of the "ForwardedForFilter" filter and then the X-Forwarded-For header will be set whenever requests are forwarded to those backend servers.    The changes are as follows, as per the sample in the sps-site-specific subdirectory of the zip file

The changes are fairly simple, (also included in the sps-site-sepecific directory in the zip file) simply change :




  <nete:forward filter="ForwardedForFilter">$0</nete:forward>


1.5  XForwardForFilter Parameter Values

The parameters for ForwardForFilter filter in server.conf are :


  • debugTraceLevel = 0|1|2|3
    A simple print to stdout trace facility higher level prints more details
  • XforwardForHeaderName = “X-Forwarded-For”
    Identifies the name of the header that will be set in the HTTP request sent onto the backend server (usually the default value "X-Forwarded-For" will be what you require)
  • mode = Append | Overwrite
    Identifies what to do if an X-Forward-For header already exists.  The default is to Append which adds the IP address we captured to the chain of prior proxies.  But if the prior server is not a trusted server, then Overwrite may be a better choice for youe situation.
  • enabled = True | False
    Just a quick way to enable|disable the filter via configuration. The default is enabled so it is set to true.


1.6 Verify that it is working correctly.

The best way to verify the result is to enable httpclient logging, via editing server.conf, and change the setitng : httpclientlogging="yes".  Then you can view the request as it is passed onto the backend : Chopping out the extra stuff, you should see the request to the backend, now contians the X-Forwarded-For header : 

>> "GET /us/default.aspx HTTP/1.1[\r][\n]"

>> "Accept-Language: en-US[\r][\n]"

>> "connection: Keep-Alive[\r][\n]"

>> "content-length: 0[\r][\n]"

>> "accept: image/jpeg, image/gif, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*[\r][\n]"

>> "Accept-Encoding: gzip, deflate[\r][\n]"

>> "user-agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729)[\r][\n]"

>> "X-Forwarded-For:[\r][\n]"
>> "Host:[\r][\n]"

>> "[\r][\n]"


1.6 Coding the custom SPSFIlter

The code requires is very simple, in the custom SPSFilter, we create a doPreFilter() method, to manipulate the request prior to it being sent to the backend.  Within the method we use the normal tomcat/Java Servlet method to get the client IP address which has been passed from Apache and then set the X-Forwarded-For header:


* Prefilter process to update the X-Forwarded-For: header.


public void doPreFilter(ProxyRequest prequest, ProxyResponse presponse) throws ProxyFilterException {


    String remoteAddr = prequest.getOriginalRequest().getRemoteAddr();


    prequest.setHeader("X-Forwarded-For", remoteAddr);



The real code is only slightly more complex, doing some logging and be able to work with the header when it already exists. 

1.7 Compiling Source Code

The zip file contains the source code is in filter/src subdirectory, and there is also a sample build script: build.bat and file provided.

The build process is fairly simple, to compile you just need to edit the build.bat/ file, verify or update the location of the SDK install,

set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_31\

And then run the build script.  That will create the SPSForwadedForFilter.jar file.  Often it
is easiest to do the build on the SPS machine itself, since then you are ensured of having a compatable JRE version.



The following disclaimer applies to all code uploaded to the CA Security Community site,


Folders may contain scripts, tools and documents ('Files') for the CA SiteMinder solutions from CA Technologies.  This content has been uploaded by fellow community members and has not been checked, tested, or approved by CA Technologies (or anyone else).  NEITHER CA, INC. NOR ANY OF ITS SUBSIDIARIES AND AFFILIATES (CA's) NOR ANY COMMUNITY MEMBER SHALL BE LIABLE TO THE OTHER OR ANY OTHER MEMBER OR THIRD PARTY FOR DIRECT, CONSEQUENTIAL, INCIDENTAL, INDIRECT AND/OR SPECIAL DAMAGES FOR ANY CLAIMS ARISING FROM OR IN ANY WAY CONNECTED WITH YOUR DECISION TO ACCESS OR USE ANY SUCH FILES, EVEN IF THE POSSIBILITY OF SUCH DAMAGES IS, OR SHOULD HAVE BEEN, KNOWN. THESE FILES ARE PROVIDED AS IS WITHOUT ANY warranty or representation of any kind express or implied including without limitation Any Implied warranty of merchantability/satisfactory quality, fitness for a particular purpose or non-infringment. Your usage of any such Files is at your own risk. You are solely responsible for testing such Files prior to implementing them in either a test or production environment. We encourage you to check for any documentation (if provided) by looking in the document comments or on the message boards for a corresponding thread for additional information (if available). It is recommended to deploy/implement in a test or QA environment before implementing in a production environment. Such Files are not covered by CA's Support Policy and Terms. CA will not under any circumstances support them.  

Source sample .tar.gz attached

Cheers – Mark O'Donohue - [ ]


4 people found this helpful