多级反向代理下,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,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是 在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问 http://www.javapeixun.com.cn /index.jsp/ 时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问http://192.168.1.110:2046 /index.jsp ,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过 request.getRemoteAddr()的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。
于是可得出获得客户端真实IP地址的方法一:
- publicif) == nullreturnreturn);
- }
可是当我访问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地址的方法二:
- public);
- ifnull || .equalsIgnoreCase(ip)) {
- );
- ifnull || .equalsIgnoreCase(ip)) {
- );
- ifnull || .equalsIgnoreCase(ip)) {
- return }
可是,如果通过了多级反向代理的话,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
- * @param request
- * @return
- */
- public String getIpAddr(HttpServletRequest request){
- String ipAddress = request.getHeader("x-forwarded-for");
- if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
- ipAddress = request.getHeader("Proxy-Client-IP");
- }
- if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
- ipAddress = request.getHeader("WL-Proxy-Client-IP");
- }
- if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
- ipAddress = request.getRemoteAddr();
- if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
- //根据网卡取本机配置的IP
- InetAddress inet=null;
- try {
- inet = InetAddress.getLocalHost();
- } catch (UnknownHostException e) {
- e.printStackTrace();
- }
- ipAddress= inet.getHostAddress();
- }
- }
- //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
- if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
- if(ipAddress.indexOf(",")>0){
- ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
- }
- }
- return ipAddress;
- }
以上内容均来自网络。鄙人只是对其整合。望对大家帮助!
多级反向代理下,Java获取请求客户端的真实IP地址多中方法整合的更多相关文章
- Java获取请求客户端的真实IP地址
整理网友的材料,最后有源码,亲测能解决所有java获取IP真实地址的问题 整理的这里: 1.链接1 2.链接2 JSP里,获取客户端的IP地址的方法是: request.getRemoteAddr() ...
- java 获取请求客户端的真实IP地址
转载自:http://leiyongping88.iteye.com/blog/1545930 用request.getRemoteAddr();方法获取的IP地址是:127.0.0.1或192.16 ...
- 服务器受到网络攻击时,如何获取请求客户端的真实 IP?
网络攻击 前不久公司遭受了一次网络攻击. 早晨刚到公司,就发现登录接口的调用次数飙升,很快就确认是被恶意攻击,让安全部门做网关入口针对对方 IP 加了限制. 并统一对所有的 IP 加了调用的频率限制. ...
- nginx反向代理下没有获取到正确的clientIP问题发散
问题背景: 在使用nginx服务器NginxA 来反向代理服务 WebAPIA,WebAPIA中要获取ClientIP,结果获取到的IP为NginxA的, 于是引出了以下的一连串概念... 首先使用X ...
- 通过HttpservletRequest对象获取客户端的真实IP地址
这篇文章主要介绍了Java中使用HttpRequest获取用户真实IP地址,使用本文方法可以避免Apache.Squid.nginx等反向代理软件导致的非真实IP地址,需要的朋友可以参考下 在JSP里 ...
- java 获取的是本地的IP地址
1 public static void main(String[] args) { 2 try { 3 InetAddress address = InetAddress.getLocalHost( ...
- php 获取客户端的真实ip地址 通过第三方网站
<?php include 'simple_html_dom.php'; // 1获取真实IP地址方式 function get_onlineip() { $ch = curl_init('ht ...
- TFS应用层服务器获取F5用户的真实IP地址(高可用性)
当用户数量达到一定级别(例如2千)以上,为保证TFS系统的持续服务,最大程度减少因系统宕机对研发团队的影响,系统管理员一般会考虑应用层和数据库层的高可用性方案. 在应用层的高可用性方案中,目前比较常见 ...
- Nginx反向代理下IIS获取真实IP
1. iis 如果放在反向代理后面,日志里的c-ip是反向代理服务器的ip,不是真正用户的ip,想要记录用户的ip要做两件事. 一.在反向代理设置X-Forwarded-For段,以下为nginx下的 ...
随机推荐
- Libliner 中的-s 参数选择:primal 和dual
Libliner 中的-s 参数选择:primal 和dual LIBLINEAR的优化算法主要分为两大类,即求解原问题(primal problem)和对偶问题(dual problem).求解原问 ...
- apache 伪静态配置
1 现配置站点, <VirtualHost *:80> //访问名称 ServerName my.seo_demo.com //项目地址 DocumentRoot "/Users ...
- java中的枚举类型
枚举类型是那些字段由一组固定常量组成的类型.常见的例子有:东南西北四个方向,星期几等. 所有枚举类型都隐式继承java.lang.Enum类型,因为java不支持多重继承,所以枚举不能继承其他任何类. ...
- java发送邮件
1.需要用到javax.mail怎么下载呢?百度javax.mail就会看见http://www.oracle.com/technetwork/java/index-138643.html实际上这个项 ...
- windows 内部预览版与迅雷极速版不配合
为了体验bash on ubuntu安装的预览版本,结果原来的迅雷极速版本无法成功下载文件,总是在最后一刻报错退出. 解决方法是: 下载安装迅雷9 哈哈哈哈,新版迅雷挺不错的,运行良好. ctrl^v ...
- 通过Gearman实现MySQL到Redis的数据同步
对于变化频率非常快的数据来说,如果还选择传统的静态缓存方式(Memocached.File System等)展示数据,可能在缓存的存取上会有很大的开销,并不能很好的满足需要,而Redis这样基于内存的 ...
- android 布局之scrollview
今天在布局页面的时候后犯了难,我要显示的内容一个页面展示不完,怎么办呢? 于是随便找了个app点开一看,哎呀原来还能翻动啊!这是啥布局呢?原来是ScrollView 官方api相关的内容全是英文,这可 ...
- php学习手记
在学习常量的时候,一直觉得奇怪 为啥常量的时候总是有个“.”在常量的后面,经过学习现在得知该点是 相当于Java当中的“+”用于连接字符 <?php header("Content-t ...
- js-jquery-将table的td转化成可编辑的文本
1.使用插件mindmup-editabletable.js $('#table').editableTableWidget({editor: $('<textarea>')}); 2.j ...
- Windows上python的virtualenv 安装及使用
源地址:http://blog.csdn.net/liuchunming033/article/details/46008301 VirtualEnv可以方便的解决不同项目对类库的依赖问题. 现实测试 ...