`
skydove
  • 浏览: 19310 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

Java获取客户端IP地址及注意事项

阅读更多

 

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

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

    于是可得出获得客户端真实IP地址的方法一:

Java代码:

public String getRemortIP(HttpServletRequest request) {

  if (request.getHeader("x-forwarded-for") == null) {

    return request.getRemoteAddr();

  }

  return request.getHeader("x-forwarded-for");

}

   可是当我访问http://www.5a520.cn /index.jsp/ 时,返回的IP地址始终是unknown,也并不是如上所示的127.0.0.1 或 192.168.1.110了,而我访问http://192.168.1.110:2046/index.jsp 时,则能返回客户端的真实IP地址,写了个方法去验证。原因出在了Squid上。squid.conf 的配制文件 forwarded_for 项默认是为on,如果 forwarded_for 设成了 off  则:X-Forwarded-For: unknown


于是可得出获得客户端真实IP地址的方法二:

Java代码:

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; 

}

    可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串Ip值,究竟哪个才是真正的用户端的真实IP呢?

    答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。

    如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100用户真实IP为: 192.168.1.110

 

最近做一个安全系统,需要对用户的 ip 和 mac 地址进行验证,这里用到获取客户端ip和mac地址的两个方法,留存。

获取客户端mac地址

调用window的命令,在后台Bean里实现 通过ip来获取mac地址。方法如下:

public String getMACAddress(String ip){

   String str = "";

   String macAddress = "";

   try {

        Process p = Runtime.getRuntime().exec("nbtstat -A " + ip);

        InputStreamReader ir = new InputStreamReader(p.getInputStream());

        LineNumberReader input = new LineNumberReader(ir);

        for (int i = 1; i < 100; i++) {

             str = input.readLine();

             if (str != null) {

                 if (str.indexOf("MAC Address") > 1) {

                     macAddress = str.substring(str.indexOf("MAC Address") + 14, str.length());

                     break;

                 }

             }

        }

   } catch (IOException e) {

        e.printStackTrace(System.out);

   }

   return macAddress;

}

补充:

关于获取IP地址的方式,最近在linux下有一个教训,如果单纯通过InetAddress来获取IP地址,就会出现在不同的机器上IP地址不同的问题。

InetAddress.getLocalHost().getAddress() 实际上是根据hostname来获取IP地址的。linux系统在刚刚装完默认的hostname是localhost,所以通过上面代码获取到的本机ip就是127.0.0.1, 相对应,比如我的hostname就是rjlin.atsig.com 返回的ip地址确是atsig.com的地址。暂时采用下面代码来处理,当然还不够灵活:

public static byte[] getIp() throws UnknownHostException {

byte[] b = InetAddress.getLocalHost().getAddress();

Enumeration allNetInterfaces = null;

try {

allNetInterfaces = NetworkInterface.getNetworkInterfaces();

} catch (SocketException e) {

e.printStackTrace();

}

InetAddress ip = null;

NetworkInterface netInterface = null;

while (allNetInterfaces.hasMoreElements()) {

netInterface = (NetworkInterface) allNetInterfaces.nextElement();

if (netInterface.getName().trim().equals("eth0")){

Enumeration addresses = netInterface.getInetAddresses();

while (addresses.hasMoreElements()) {

ip = (InetAddress) addresses.nextElement();

}

break;

}

}

if (ip != null && ip instanceof Inet4Address) {

return b = ip.getAddress();

}

return b;

}

 

上面代码看来起是正常的.可惜这里却隐藏了一个隐患!!因为"X_FORWARDED_FOR"这个值是通过获取HTTP头的"X_FORWARDED_FOR"属性取得.所以这里就提供给恶意破坏者一个办法:可以伪造IP地址!! 可以直接使用java设置X_FORWARDED_FOR的值,甚至可以设置可执行的sql语句,因此在此判断校验要非常小心。

 

分享到:
评论

相关推荐

    jsp获取客户端IP地址的方法.docx

    对于使用Java Server Pages (JSP) 的开发者来说,了解如何高效地获取客户端IP地址至关重要。本文将详细介绍几种在JSP环境中获取客户端IP地址的有效方法,并提供实际的代码示例。 #### 二、获取客户端IP地址的重要性...

    用Java来获取访问者真实的IP地址

    但是当请求经过反向代理时,代理服务器会将原始的客户端IP地址信息附加在HTTP请求头中,通常使用`X-Forwarded-For`字段来传递这些信息。因此,为了获得客户端的真实IP地址,我们需要从HTTP请求头中读取这个字段的...

    JAVA获取别人的ip地址

    ### JAVA获取别人IP地址的方法与实现 #### 一、引言 在开发网络应用程序时,经常需要获取客户端的IP地址。这不仅可以用于日志记录、统计分析,还可以用于某些安全控制措施,例如限制某些IP访问服务等。本文将详细...

    获取访问者真实的IP地址

    3. **处理 `REMOTE_ADDR`**:如果以上两种方式都无法获取到有效的IP地址,则直接使用`request.getRemoteAddr()`方法获取客户端IP地址。需要注意的是,这种方式获取的可能是代理服务器的IP地址而非客户端的真实IP地址...

    JSP如何获取客户端真实IP地址

    在没有反向代理的简单情况下,可以通过request对象的getRemoteAddr()方法来获取客户端IP地址。然而,在实际的生产环境中,许多网络架构都部署了反向代理服务器,如Apache、Squid等,这使得获取客户端真实IP变得复杂...

    用java实现获取MAC地址的方法

    通过上述代码,我们实现了使用Java获取远程主机MAC地址的功能。需要注意的是,这种方法受限于操作系统的限制,并且可能存在一定的安全风险。在生产环境中部署此类功能前,建议进行充分的测试并采取适当的安全措施。

    JSP获取客户端的浏览器和操作系统信息

    - `request.getRemoteAddr()`:获取客户端IP地址。 - `request.getRemoteHost()`:获取客户端主机名(如果不可用,则返回IP地址)。 - `request.getProtocol()`:获取协议名称和版本。 #### 五、最佳实践与注意事项...

    java socket长连接客户端服务端(标准实例)

    1. 建立连接:客户端使用`Socket`类的构造函数,指定服务器的IP地址和端口号,如`new Socket("localhost", 8080)`。 2. 数据传输:通过Socket对象的输入流和输出流进行数据读写,通常使用`BufferedReader`和`...

    java编写的简单c/s通讯程序

    #### 四、注意事项 - **异常处理**: - 在实际编程过程中,网络编程往往伴随着各种异常,如连接失败、读写超时等。因此,在代码中加入异常处理机制非常重要。 - **资源管理**: - 为避免资源泄露,确保在使用完...

    java_socket服务端和客户端编程.doc

    #### 七、注意事项与优化建议 - **性能优化**: - 对于TCP协议,可以通过调整缓冲区大小、使用非阻塞I/O等方式提高性能。 - 对于UDP协议,考虑到其不可靠性,可以采用重传机制等策略保证数据的可靠性。 - **安全...

    java 单聊 群聊

    - 创建`Socket`实例,指定服务器的IP地址和端口号,发起连接请求。 - 连接建立后,可以通过`Socket`的输入输出流进行数据交换。`Socket.getInputStream()`获取输入流,用于读取服务器发送的数据;`Socket....

    整合java实例 FastDFS

    1. **配置文件**:首先,需要配置FastDFS的连接参数,如tracker服务器的IP地址和端口,这些信息通常在`client.conf`文件中设置。 2. **连接Tracker**:在Java代码中,通过初始化`FdfsClient`,建立与Tracker服务器...

    JAVA链接Redis需要使用到的jar包

    - Redis服务器的IP地址和端口号需要根据实际情况配置。 - 为了保证连接安全性,可以考虑使用SSL连接或者配置认证信息。 - 定期进行连接池维护,如定时检测并回收失效连接。 - 根据应用需求调整连接池的参数,...

    java实现daytime协议

    - **客户端**:首先,客户端需要创建一个`Socket`对象,指定服务器的IP地址和端口号。然后,通过`Socket`的`getInputStream()`方法获取输入流,读取服务器返回的时间数据。最后,关闭网络连接。 - **服务器端**:...

    Java Socket使用实例

    6. **注意事项**:在实际应用中,要处理异常情况,确保资源的正确关闭,防止内存泄漏。同时,为了提高程序的健壮性,可以使用多线程处理客户端连接,使得服务器能够同时处理多个客户端。 这个"Java Socket使用实例...

    JAVA与android之间通过socket通信

    1. **Socket类的创建**:在Java中,我们首先需要通过`Socket`类创建一个客户端Socket实例,指定服务器的IP地址和端口号。例如: ```java Socket socket = new Socket("服务器IP", 服务端口); ``` 2. **输入/...

    利用Java Sock实现C/S通信

    1. 创建Socket实例,指定服务器的IP地址和端口号,建立连接。 2. 获取Socket的输入流和输出流,用于接收服务器数据和发送数据。 3. 编写发送数据的逻辑,通过输出流写入数据到网络。 4. 循环读取输入流,显示接收到...

    AWS S3 Java 开发文档

    其中,`accessKey`和`secretKey`是用户在AWS控制台创建的访问密钥,而`hostname`是S3服务的地址,可以是域名或者IP地址。如果使用的是域名,并且服务端不支持默认格式`bucket.hostname`,需要使用`S3ClientOptions`...

    电信SMGP协议java实现

    注意事项** - 确保网络环境畅通,SMSC服务器可访问。 - 了解并遵循SMGP协议规范,避免因错误的数据格式导致通信失败。 - 对异常情况进行处理,如连接超时、数据解析错误等。 - 考虑性能优化,如连接池的使用、心跳...

    Socket单客户端实现对话功能

    4. **注意事项**: - 修改IP地址:在运行客户端代码时,必须确保输入的IP地址是服务器端的实际IP,否则连接无法建立。 - 错误处理:在实际开发中,需要处理各种可能的异常,如网络连接错误、数据传输错误等。 - ...

Global site tag (gtag.js) - Google Analytics