In a simple way, you can’t get the IP address of the client’s request. But you can use the below approach, that will work for sure.
public static String getClientIpAddr(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.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(); } return ip; }
Cover image credits: Image by Author | Get IP Address using java
More explanation
request.getRemoteAddr()
is the way. It appears your proxy changes the source IP. When some proxies do that they add the original IP in some custom HTTP header. Use request.getHeaderNames()
and request.getHeaders(name)
and print all of them to see if there isn't anything of interest. Like X-CLIENT-IP
(made that one up, but they look like this)
As this is usually a deployment concern, rather than an application concern, another approach would be to configure the application container appropriately. Once configured, the container takes care of inspecting the appropriate header and your application continues to use request.getRemoteAddr()
.
For example, in Tomcat you can use the Remote IP Valve. I would assume most application servers have similar functionality.
The container could also take care of understanding if your front-end load balancer is terminating SSL connections, forwarding the request to the app server over HTTP. This is important when your application needs to generate URLs to itself.
- If your servlet is running on a web server 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.
- 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 inserts 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 de facto 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 the 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.
If you find joy and value in what I write, please consider supporting my work with a donation — however much you can afford, it means and helps more than you can imagine. Buy Me A Coffee.
References:
Discover more from 9Mood
Subscribe to get the latest posts sent to your email.
0 Comments