28

I find some different ways to get ip in servlet. but i don't know which one is right and why.

1:

request.getHeader( "X-Real-IP" )

2:

  String ip = request.getHeader("X-Forwarded-For"); 
  if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
        ip = request.getHeader("Proxy-Client-IP");  
    }  
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
        ip = request.getHeader("WL-Proxy-Client-IP");  
    }  
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
        ip = request.getHeader("HTTP_CLIENT_IP");  
    }  
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");  
    }  
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
        ip = request.getRemoteAddr();  
    } `

3:

 String ip=request.getHeader("x-forwarded-for");
                if(ip==null){
                    ip=request.getRemoteAddr();
                }
                String ips[]=ip.split(",");`
                                ip=ips[0];
aizaz
  • 2,948
  • 9
  • 23
  • 55
sprite
  • 514
  • 1
  • 4
  • 11
  • Check this link: http://stackoverflow.com/questions/10363069/how-can-i-retrieve-ip-address-from-http-header-in-java/10363109#10363109 –  Aug 21 '13 at 06:37

2 Answers2

59

The answer is complicated.

  • If your servlet is running on a webserver that is behind a reverse proxy or load balancer, then that web proxy can be configured to inject a request header that gives the IP address that the request came from. Different reverse proxies will inject different headers. Consult the documentation for your (front-end) server.

  • If your client uses a (forward) proxy, then it might insert headers to say what the client IP address is ... or it might not. And the IP address it insert might be incorrect.

  • The value you get by calling request.getRemoteAddr() is going to be the IP address of the immediate upstream source of the request.

None of the headers that you listed is standard, but "x-forwarded-for" is reputed to be a defacto standard; i.e. it is the one that is most likely to be inserted by a proxy, etc ... if anything is injected.

Finally, even if you did get an IP address, it wouldn't necessarily help you. For instance, if the client sits on a private network and connects to the internet via a NAT gateway, then the IP address in HTTP request will be an address of the NAT server ... not the actual client IP.


So what does this all mean? Well basically, it means that in general you cannot reliably find out the IP address of the system that the request originated from.

Stephen C
  • 632,615
  • 86
  • 730
  • 1,096
  • thank you for you great answer, we use nginx+tomcat+spring +spring mvc+mybatis ,i am in china, this is my second question on stackoverflow,my first is failed--!. i think that we should do much more tests on it. – sprite Aug 22 '13 at 01:54
  • @sprite - you should check the nginx documentation to find out what header it is using. But that will only give you the IP address of the next upstream host ... which may not be the real client. As I said, you can't always get the real client IP ... and even if you could, it would not necessarily be either reliable, useful or unique. – Stephen C Aug 23 '13 at 04:14
  • ok,i almost understand your advice. Is 'the IP address of the next upstream host' means the last proxy's ip address?@Stephen C – sprite Aug 26 '13 at 02:57
  • @sprite - Yes. That is the only IP address available at the network level. (And come to think of it, you can't entirely rely on *that* IP address to be authentic ... given that IP addresses can be spoofed.) – Stephen C Aug 26 '13 at 03:49
20

This seems the most we can do to get the original IP address of the client

String ipAddress = request.getHeader("X-FORWARDED-FOR");  
if (ipAddress == null) {  
   ipAddress = request.getRemoteAddr();  
}
Audrius Meskauskas
  • 18,378
  • 9
  • 63
  • 78
Burak Keceli
  • 883
  • 1
  • 14
  • 29
  • 5
    Except when it doesn't; see my Answer. – Stephen C Nov 19 '14 at 03:23
  • 9
    This will not work since the X-Forwarded-For can contain a comma separated (optionally with white space) list of proxy IP-addresses! – Yeti Jan 10 '15 at 11:13
  • It can, but as the other answers already point out, the value all depends on the configuration of _your_ proxy, in which case you would overwrite any such upstring headers as a security precaution, as they cannot be trusted. – Morten Haraldsen Nov 14 '16 at 07:23