在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语句,因此在此判断校验要非常小心。
分享到:
相关推荐
对于使用Java Server Pages (JSP) 的开发者来说,了解如何高效地获取客户端IP地址至关重要。本文将详细介绍几种在JSP环境中获取客户端IP地址的有效方法,并提供实际的代码示例。 #### 二、获取客户端IP地址的重要性...
但是当请求经过反向代理时,代理服务器会将原始的客户端IP地址信息附加在HTTP请求头中,通常使用`X-Forwarded-For`字段来传递这些信息。因此,为了获得客户端的真实IP地址,我们需要从HTTP请求头中读取这个字段的...
### JAVA获取别人IP地址的方法与实现 #### 一、引言 在开发网络应用程序时,经常需要获取客户端的IP地址。这不仅可以用于日志记录、统计分析,还可以用于某些安全控制措施,例如限制某些IP访问服务等。本文将详细...
3. **处理 `REMOTE_ADDR`**:如果以上两种方式都无法获取到有效的IP地址,则直接使用`request.getRemoteAddr()`方法获取客户端IP地址。需要注意的是,这种方式获取的可能是代理服务器的IP地址而非客户端的真实IP地址...
在没有反向代理的简单情况下,可以通过request对象的getRemoteAddr()方法来获取客户端IP地址。然而,在实际的生产环境中,许多网络架构都部署了反向代理服务器,如Apache、Squid等,这使得获取客户端真实IP变得复杂...
通过上述代码,我们实现了使用Java获取远程主机MAC地址的功能。需要注意的是,这种方法受限于操作系统的限制,并且可能存在一定的安全风险。在生产环境中部署此类功能前,建议进行充分的测试并采取适当的安全措施。
- `request.getRemoteAddr()`:获取客户端IP地址。 - `request.getRemoteHost()`:获取客户端主机名(如果不可用,则返回IP地址)。 - `request.getProtocol()`:获取协议名称和版本。 #### 五、最佳实践与注意事项...
1. 建立连接:客户端使用`Socket`类的构造函数,指定服务器的IP地址和端口号,如`new Socket("localhost", 8080)`。 2. 数据传输:通过Socket对象的输入流和输出流进行数据读写,通常使用`BufferedReader`和`...
#### 四、注意事项 - **异常处理**: - 在实际编程过程中,网络编程往往伴随着各种异常,如连接失败、读写超时等。因此,在代码中加入异常处理机制非常重要。 - **资源管理**: - 为避免资源泄露,确保在使用完...
#### 七、注意事项与优化建议 - **性能优化**: - 对于TCP协议,可以通过调整缓冲区大小、使用非阻塞I/O等方式提高性能。 - 对于UDP协议,考虑到其不可靠性,可以采用重传机制等策略保证数据的可靠性。 - **安全...
- 创建`Socket`实例,指定服务器的IP地址和端口号,发起连接请求。 - 连接建立后,可以通过`Socket`的输入输出流进行数据交换。`Socket.getInputStream()`获取输入流,用于读取服务器发送的数据;`Socket....
1. **配置文件**:首先,需要配置FastDFS的连接参数,如tracker服务器的IP地址和端口,这些信息通常在`client.conf`文件中设置。 2. **连接Tracker**:在Java代码中,通过初始化`FdfsClient`,建立与Tracker服务器...
- Redis服务器的IP地址和端口号需要根据实际情况配置。 - 为了保证连接安全性,可以考虑使用SSL连接或者配置认证信息。 - 定期进行连接池维护,如定时检测并回收失效连接。 - 根据应用需求调整连接池的参数,...
- **客户端**:首先,客户端需要创建一个`Socket`对象,指定服务器的IP地址和端口号。然后,通过`Socket`的`getInputStream()`方法获取输入流,读取服务器返回的时间数据。最后,关闭网络连接。 - **服务器端**:...
6. **注意事项**:在实际应用中,要处理异常情况,确保资源的正确关闭,防止内存泄漏。同时,为了提高程序的健壮性,可以使用多线程处理客户端连接,使得服务器能够同时处理多个客户端。 这个"Java Socket使用实例...
1. **Socket类的创建**:在Java中,我们首先需要通过`Socket`类创建一个客户端Socket实例,指定服务器的IP地址和端口号。例如: ```java Socket socket = new Socket("服务器IP", 服务端口); ``` 2. **输入/...
1. 创建Socket实例,指定服务器的IP地址和端口号,建立连接。 2. 获取Socket的输入流和输出流,用于接收服务器数据和发送数据。 3. 编写发送数据的逻辑,通过输出流写入数据到网络。 4. 循环读取输入流,显示接收到...
其中,`accessKey`和`secretKey`是用户在AWS控制台创建的访问密钥,而`hostname`是S3服务的地址,可以是域名或者IP地址。如果使用的是域名,并且服务端不支持默认格式`bucket.hostname`,需要使用`S3ClientOptions`...
注意事项** - 确保网络环境畅通,SMSC服务器可访问。 - 了解并遵循SMGP协议规范,避免因错误的数据格式导致通信失败。 - 对异常情况进行处理,如连接超时、数据解析错误等。 - 考虑性能优化,如连接池的使用、心跳...
4. **注意事项**: - 修改IP地址:在运行客户端代码时,必须确保输入的IP地址是服务器端的实际IP,否则连接无法建立。 - 错误处理:在实际开发中,需要处理各种可能的异常,如网络连接错误、数据传输错误等。 - ...