views:

397

answers:

2

We need to log the client's IP address from a Seam action. Currently, we're using the code:

ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
HttpServletRequest request = (HttpServletRequest)context.getRequest();

this.remoteAddress =  request.getRemoteAddr();

However, this seems to be always returning an internal address of our network, rather than the client's IP address. From my research, it seems that having a reverse proxy in the network can confuse things, but we might be able to fix it by reconfiguring our web servers. Has anyone else had this problem, and how did you solve it?

We're using JBoss 5.1 app servers and Apache web servers. Thanks!

A: 

You can 'see through' a proxy and get the address of the original requestor from the X_FORWARDED_FOR header using

request.getHeader( "X_FORWARDED_FOR" );

I guess a misbehaving proxy between the original requestor and your server could result in the true value being lost.

Ref: wikipedia description of X_FORWARDED__FOR

martin clayton
That will help for a HTTP proxy, but not so much for a NAT firewall.
bmargulies
Thanks that's good information, but what could make a proxy misbehave? My understanding is that if everything is configured correctly, then request.getRemoteAddr() should be looking at the "x_forwarded_for" header anyway, and if it's not set up correctly, that header might not even be there.
Greg Charles
+1  A: 

What you need is for your reverse proxy to pass the original IP address in a special header, like x-forwarded-for. You can then retrieve this header from your servlet. Additionally, you may want to modify your log file to log this IP address. Example:

    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"  
           prefix="access_log." suffix=".txt"
           fileDateFormat="yyyy-MM-dd"
           pattern="%{x-forwarded-for}i %l - %t &quot;%r&quot; %s %b &quot;%{referer}i&quot; &quot;%{user-agent}i&quot;"
           resolveHosts="false"/>
brianegge