在Servlet里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid,Nginx等反向代理软件就不能获取到客户端的真实IP地址了。

如果使用了反向代理软件,例如将http://192.168.101.88:80/ 的URL反向代理为http://pay.kedou.com/ 的URL时,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或192.168.101.88,而并不是客户端的真实IP。

如下图,原来是client端直接请求服务端,走A路线请求,这时候通过request.getRemoteAddr()方法可以准备的获取客户端的IP。但是做了代理之后呢,client端不是直接请求服务端,而是走B线路请求代理服务器,由代理器去请求服务端,这时候服务端通过request.getRemoteAddr()方法拿到的理所当然是代理服务器的地址了。

经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问http://www.xxx.com/index.jsp/ 时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问http://192.168.1.110:2046/index.jsp ,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过request.getRemoteAddr()的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。

下面的获取真实IP的Java类:

/**
* 常用获取客户端信息的工具
*
*/
public final class NetworkUtil {
/**
* Logger for this class
*/
private static Logger logger = Logger.getLogger(RandomCodeUtils.class); /**
* 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址;
*
* @param request
* @return
* @throws IOException
*/
public final static String getIpAddress(HttpServletRequest request) throws IOException {
// 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址 String ip = request.getHeader("X-Forwarded-For");
if (logger.isInfoEnabled()) {
logger.info("getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip=" + ip);
} if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
if (logger.isInfoEnabled()) {
logger.info("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip=" + ip);
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
if (logger.isInfoEnabled()) {
logger.info("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip=" + ip);
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
if (logger.isInfoEnabled()) {
logger.info("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip=" + ip);
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
if (logger.isInfoEnabled()) {
logger.info("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip=" + ip);
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if (logger.isInfoEnabled()) {
logger.info("getIpAddress(HttpServletRequest) - getRemoteAddr - String ip=" + ip);
}
}
} else if (ip.length() > 15) {
String[] ips = ip.split(",");
for (int index = 0; index < ips.length; index++) {
String strIp = (String) ips[index];
if (!("unknown".equalsIgnoreCase(strIp))) {
ip = strIp;
break;
}
}
}
return ip;
}
}

Request获取用户真实IP(用作白名单过滤)的更多相关文章

  1. java 获取用户真实ip

    /** * 获取用户真实ip * @param request * @return */ public static String getIpAddr(HttpServletRequest reque ...

  2. Java中使用HttpRequest获取用户真实IP地址端口

    import javax.servlet.http.HttpServletRequest; /** * 自定义访问对象工具类 * * 获取对象的IP地址等信息 * @author X-rapido * ...

  3. 在有nginx做反向代理时候,如何获取用户真实Ip信息

    在获取用户的Ip地址时,不一定可以获取到用户真实的地址信息,这要看代理服务器的类型,代理服务器有普通匿名代理服务器,高匿代理服务器,像这种情况很难获取到用户真实的Ip地址 假如用户没有使用匿名代理服务 ...

  4. 获取用户真实IP:(模拟:客户端--F5--nginx--tomcat 后端获取用户真实IP)

    模拟:客户端--F5--nginx--tomcat 后端获取用户真实IP 192.168.109.137 :nginx01(充当第一层代理==F5)192.168.109.138 :nginx02(二 ...

  5. 如何根据HttpServletRequets获取用户真实IP地址

    最近的一个项目的某个功能获取用户的ip地址,添加用户的系统使用记录. 我发现当我直接使用getRemoteAddr()方法从HttpServletRequet中获取用户的ip时,获取到的是服务器的ip ...

  6. nginx反向代理获取用户真实ip

    nginx做反向代理时,默认的配置后端获取到的ip都是来自于nginx,如何转发用户的真实ip到后端程序呢?如是是java后端,用request.getRemoteAddr();获取到的是nginx的 ...

  7. PHP获取用户真实 IP , 淘宝IP接口获得ip地理位置(转)

    <?php /** * 获取用户真实 IP */ function getIP() { static $realip; if (isset($_SERVER)){ if (isset($_SER ...

  8. 多层代理获取用户真实IP

    1. 几个概念remote_addr:如果中间没有代理,这个就是客户端的真实IP,如果有代理,这就是上层代理的IP.X-Forwarded-For:一个HTTP扩展头,格式为 X-Forwarded- ...

  9. 根据HttpServletRequest获取用户真实IP地址

    原因: 当我们通过request获取客户端IP时,自身服务器通常会为了保护信息或者负载均衡的目的,对自身服务器做反向代理.此时如果我们通过request.getRemoteAddr();可能获取到的是 ...

随机推荐

  1. 【Ubuntu】VirtualBox 您没有查看“sf_VirtualDisk”的内容所需的权限。

    转自:https://www.cnblogs.com/laishenghao/p/5346651.html 最终解决办法: sudo adduser lqr vboxsf 这里lqr是我的用户名 然后 ...

  2. django signal

    @receiver(post_save, sender=User) def create_account(sender, instance=None, **kwargs): if instance i ...

  3. spring集成RabbitMQ配置文件详解(生产者和消费者)

    1,首先引入配置文件org.springframework.amqp,如下: <dependency> <groupId>org.springframework.amqp< ...

  4. iOSTableview 禁止下拉,允许上拉

    1 回弹机制:bounces alwaysBounceHorizontal alwaysBounceVerticalbounces:描述的当scrollview的显示超过内容区域的边缘以及返回时,是否 ...

  5. libXext.so.6: cannot open shared object file:

    在64位的centos安装64位的oracle的时候,有时候会出现“libXext.so.6: cannot open shared object file:”的错误. 这个原因主要是oracle在安 ...

  6. burpsuite两个变量的爱情故事

    抓包的时候在攻击类型处选择[Cluster bomb] 在payload type这里设置类型为[simple list] 第一个是账号 第二个是密码 分批加载即可

  7. python matplotlib 画图

    import numpy as np import matplotlib.pyplot as plt from pylab import * numpy 常用来组织源数据: 使用 plot 函数直接绘 ...

  8. java基础篇---网络编程(UDP程序设计)

    UDP程序设计 在TCP的索引操作都必须建立可靠地连接,这样一来肯定会浪费大量的系统性能,为了减少这种开销,在网络中又提供了另外一种传输协议---UDP,不可靠的连接,这种协议在各个聊天工具中被广泛的 ...

  9. python MySQLdb安装和使用

    MySQLdb是Python连接MySQL的模块,下面介绍一下源码方式安装MySQLdb: 首先要下载下载:请到官方网站http://sourceforge.net/projects/mysql-py ...

  10. hive和hbase区别和联系

    作者:有点文链接:https://www.zhihu.com/question/21677041/answer/185664626来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...