55

I am developing a web application using JSP, Servlets (Container: Glassfish) in which I need to get clients IP Address.

I am getting the clients IP address, because I want to give access to some pages (like Customer maintenance forms) only on computers withing the office, I want to restrict access to those pages outside office.

Following is my code so far:

way1

String ipAddress =  request.getRemoteAddr();
System.out.println("IP Address: "+ipAddress);

way2

String ipAddress=null;
String getWay = request.getHeader("VIA");   // Gateway
ipAddress = request.getHeader("X-FORWARDED-FOR");   // proxy
if(ipAddress==null)
{
    ipAddress = request.getRemoteAddr();
}
System.out.println("IP Address: "+ipAddress);

Above code gives me different IP Address each time when I restart my computer (Shutdown->Start or Restart).

I am getting IP6 like:

fe80:0:0:0:20ca:1776:f5ff:ff15%13

Let me know what is wrong with this code?

informatik01
  • 16,038
  • 10
  • 74
  • 104
Bhushan
  • 6,151
  • 13
  • 58
  • 91
  • 6
    If the machine is behind a proxy you won't be able to get it's local IP or domain information, in any server side technology. – AllTooSir May 15 '13 at 07:13
  • @AndrewThompson I am getting the IP address, because I want to give access to some pages only on computers withing the office, I want to restrict access to those pages outside office – Bhushan May 15 '13 at 07:22
  • 2
    Do you have static ip's in your office? – Half Blood Prince May 17 '16 at 08:16

5 Answers5

80

As @martin and this answer explained, it is complicated. There is no bullet-proof way of getting the client's ip address.

The best that you can do is to try to parse "X-Forwarded-For" and rely on request.getRemoteAddr();

public static String getClientIpAddress(HttpServletRequest request) {
    String xForwardedForHeader = request.getHeader("X-Forwarded-For");
    if (xForwardedForHeader == null) {
        return request.getRemoteAddr();
    } else {
        // As of https://en.wikipedia.org/wiki/X-Forwarded-For
        // The general format of the field is: X-Forwarded-For: client, proxy1, proxy2 ...
        // we only want the client
        return new StringTokenizer(xForwardedForHeader, ",").nextToken().trim();
    }
}
Community
  • 1
  • 1
Xavier Delamotte
  • 3,519
  • 19
  • 30
  • 20
    Nice, but be careful if you are implementing security, as all of these headers are easy to fake. – Relefant Oct 22 '14 at 15:17
  • 4
    See nginx settings to prevent fake: https://devcentral.f5.com/questions/prevent-x-forwarded-for-spoofing – Grigory Kislin Feb 02 '15 at 12:04
  • I am getting null for all – Mr x Oct 24 '16 at 10:36
  • This is just as incorrect as the original answer. – Martin Feb 22 '17 at 12:47
  • Thank you @Martin, I've edited the answer to take your remarks into account. – Xavier Delamotte Feb 23 '17 at 14:49
  • 1
    Much better, now the answer deserves an upvote, not the opposite as was the case before the edit. :) However I would recommend readers of the answer to try to understand why, and ask the question wether or not they need to parse the proxy-header at all! (Headers are generally not reliable as a security measure). – Martin Feb 27 '17 at 09:59
  • In some system I'm getting its local IP address and in some other system I'm getting default gateway address, why would be that. – Arun Sudhakaran Jun 08 '17 at 09:15
35

I use the following static helper method to retrieve the IP of a client:

public static String getClientIpAddr(HttpServletRequest request) {  
    String ip = request.getHeader("X-Forwarded-For");  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("Proxy-Client-IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("WL-Proxy-Client-IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_X_FORWARDED");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_X_CLUSTER_CLIENT_IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_CLIENT_IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_FORWARDED_FOR");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_FORWARDED");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_VIA");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("REMOTE_ADDR");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getRemoteAddr();  
    }  
    return ip;  
}
Zain I.
  • 205
  • 4
  • 21
basZero
  • 4,129
  • 9
  • 51
  • 89
  • 2
    It might make sense to update the question with some possible values that you get via these headers. To start with that: The value can be just a single IPv4 address (`w.x.y.z`), but it can also be a comma-separated list of IPv4 addresses (`w.x.y.z, a.b.c.d` , in this case the client IP is always the first one), or you can get an IPv6 or you get illegal values (I observed single integers like `286` or just `UNKNOWN`) ... – basZero Mar 03 '14 at 10:35
  • 8
    This is so bad I don't know where to begin. Environment variables are not available as HTTP headers, and are completely useless to test for client IP. If there was in fact a need to test ten headers, why test them all, or why not loop. Also "unknown" is never set as a default, only if the client sets it explicitly. Even more so all of these headers could be manually set by a client to say "HAHAHA". The only method which works is in fact request.getRemoteAddr(), which is lucky because it is the last test. Checking "X-Forwarded-For" can be done (if you trust the proxy), but should be parsed! – Martin Feb 22 '17 at 12:44
  • 5
    For those interested in this solution, here's a more succinct and professional code doing the same: https://memorynotfound.com/client-ip-address-java/ – Clint Eastwood Feb 26 '18 at 17:28
7

I do like this,you can have a try

public String getIpAddr(HttpServletRequest request) {      
   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.getRemoteAddr();      
   }      
   return ip;      
}   
CloudyMarble
  • 36,908
  • 70
  • 97
  • 130
coffee
  • 97
  • 2
  • 3
    Where do all these incorrect answers originate from? This is not a correct way to test. Look at the comment to the similar answer..! – Martin Feb 22 '17 at 12:47
4

As basZero mentioned, X-Forwarded-For should be checked for comma. (Look at : http://en.wikipedia.org/wiki/X-Forwarded-For). The general format of the field is: X-Forwarded-For: clientIP, proxy1, proxy2... and so on. So we will be seeing something like this : X-FORWARDED-FOR: 129.77.168.62, 129.77.63.62.

mkilic
  • 117
  • 1
  • 2
1

I believe it is more to do with how your network is configured. Servlet is simply giving you the address it is finding.

I can suggest two workarounds. First try using IPV4. See this SO Answer

Also, try using the request.getRemoteHost() method to get the names of the machines. Surely the names are independent of whatever IP they are mapped to.

I still think you should discuss this with your infrastructure guys.

Community
  • 1
  • 1
Raza
  • 856
  • 6
  • 8
  • While client hostnames are not a way to implement security, i think this is the only answer that gets close to the actual problem. The local environment at the office, as in the local network can probably be improved to solve the problem. – Martin Feb 27 '17 at 10:15