asp.net 获取客户端IP
一、名词
首先说一下接下来要讲到的一些名词。
在Web开发中,我们大多都习惯使用HTTP请求头中的某些属性来获取客户端的IP地址,常见的属性是REMOTE_ADDR、HTTP_VIA和HTTP_X_FORWARDED_FOR。
这三个属性的含义,大概是如此:(摘自网上,欢迎指正)
REMOTE_ADDR:该属性的值是客户端跟服务器“握手”时候的IP。如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP。
X-Forwarded-For:是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。
XFF的有效性依赖于代理服务器提供的连接原始IP地址的真实性,因此, XFF的有效使用应该保证代理服务器是可信的, 比如可以通过建立可信服务器白名单的方式。
这一HTTP头一般格式如下:
X-Forwarded-For: client1, proxy1, proxy2
其中的值通过逗号+空格,把多个IP地址区分开, 最左边(client1)是最原始客户端的IP地址, 代理服务器每成功收到一个请求,就把请求来源IP地址添加到右边。 在上面这个例子中,这个请求成功通过了三台代理服务器:proxy1, proxy2 及 proxy3。请求由client1发出,到达了proxy3(proxy3可能是请求的终点)。请求刚从client1中发出时,XFF是空的,请求被发往proxy1;通过proxy1的时候,client1被添加到XFF中,之后请求被发往proxy2;通过proxy2的时候,proxy1被添加到XFF中,之后请求被发往proxy3;通过proxy3时,proxy2被添加到XFF中,之后请求的的去向不明,如果proxy3不是请求终点,请求会被继续转发。
鉴于伪造这一字段非常容易,应该谨慎使用X-Forwarded-For字段。正常情况下XFF中最后一个IP地址是最后一个代理服务器的IP地址, 这通常是一个比较可靠的信息来源。
(另附维基中对X-Forwarded-For的完整介绍:http://zh.wikipedia.org/wiki/X-Forwarded-For)
至于在使用这些属性的时候,属性的值是什么,网上查到一份这样的博文:获取用户IP地址的三个属性的区别(原作者不详)。
而在ASP.NET中,还可以通过另外一种方式获得客户端的IP地址,那就是通过Request对象中的UserHostAddress属性。在MSDN Library中,对这个属性是这样解释的:属性值是远程客户端的 IP 地址。
如果客户端使用了代理服务器,那么Request.UserHostAddress属性获得的就是代理服务器的IP地址。
二、方法
网上大多数方法的思路是:如果有代理IP,则优先获取代理IP,否则获取连接客户端的IP;或者调转过来,先获取连接客户端的IP,如获取失败,则获取代理IP。
以下方法参考博文asp.net获取客户端IP (作者comeonfyz)
/// <summary>
/// 获取客户端IP地址
/// </summary>
/// <returns>若失败则返回回送地址</returns>
public static string GetIP()
{
//如果客户端使用了代理服务器,则利用HTTP_X_FORWARDED_FOR找到客户端IP地址
string userHostAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString().Split(',')[].Trim();
//否则直接读取REMOTE_ADDR获取客户端IP地址
if (string.IsNullOrEmpty(userHostAddress))
{
userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
//前两者均失败,则利用Request.UserHostAddress属性获取IP地址,但此时无法确定该IP是客户端IP还是代理IP
if (string.IsNullOrEmpty(userHostAddress))
{
userHostAddress = HttpContext.Current.Request.UserHostAddress;
}
//最后判断获取是否成功,并检查IP地址的格式(检查其格式非常重要)
if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress))
{
return userHostAddress;
}
return "127.0.0.1";
} /// <summary>
/// 检查IP地址格式
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public static bool IsIP(string ip)
{
return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
}
但是这样做有一个很严重的缺陷,那就是如大牛Kingthy在其博文 使用HTTP_X_FORWARDED_FOR获取客户端IP的严重后果 中所说的,"HTTP_X_FORWARDED_FOR"这个值是通过获取HTTP头的"X_FORWARDED_FOR"属性取得的,恶意破坏者可以很轻松地伪造IP地址;而且上文特别提到过,XFF的有效性依赖于代理服务器提供的连接原始IP地址的真实性,因此, XFF的有效使用应该保证代理服务器是可信的。但是作为开发者,我们既不知道用户的IP地址的真实性,更是难以分辨代理服务器的可信性。
因此,综合各个方面的资料,我个人的想法与大牛Kingthy一样:无视代理。
/// <summary>
/// 获取客户端IP地址(无视代理)
/// </summary>
/// <returns>若失败则返回回送地址</returns>
public static string GetHostAddress()
{
string userHostAddress = HttpContext.Current.Request.UserHostAddress; if (string.IsNullOrEmpty(userHostAddress))
{
userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
} //最后判断获取是否成功,并检查IP地址的格式(检查其格式非常重要)
if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress))
{
return userHostAddress;
}
return "127.0.0.1";
} /// <summary>
/// 检查IP地址格式
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public static bool IsIP(string ip)
{
return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
}
三、总结
无视代理服务器肯定不是最好的解决方案,如果项目需求明确说要客户端的真实地址,那肯定就不能无视代理服务器了。
另外,我也向Artech大牛请教过这方面的问题,他虽然对这些没有深入的研究,但是他也认为没有一种IP获取方式是完全值得信赖的,因为这是TCP/IP协议本身决定的。
附上Artech大牛给我的一份资料,分享分享。http://www.symantec.com/connect/articles/ip-spoofing-introduction
asp.net 获取客户端IP的更多相关文章
- ASP.NET获取客户端IP及MAC地址
朋友最近问如何获取客户端IP及MAC地址,一直想把这段给整理一下,契机来了:下边分为了C#后台获取的方法和前台Javascript(调用ActiveX)获取的方法,大家如果有好的方法一起讨论撒O(∩_ ...
- asp.net获取客户端IP方法(转载)
最近web获取客户端ip,看到下面这篇文章,转载过来,一起分享(转载地址:http://www.cnblogs.com/yejun/archive/2008/02/26/1082485.html) 通 ...
- ASP.NET获取客户端IP/用户名等信息
1. 在ASP.NET中专用属性: 获取服务器电脑名:Page.Server.ManchineName 获取用户信息:Page.User 获取客户端电脑名:Page.Request.UserHostN ...
- [Asp.Net]获取客户端ip和mac地址
摘要 有时候,我们需要获取客户端的一些信息,以便进行统计.比如:客户端的唯一标识,ip等信息 IP 通过获取HTTP_X_FORWARDED_FOR,或者REMOTE_ADDR可以获取客户端的ip. ...
- ASP.NET 获取客户端IP地址
我们用Request.ServerVariables( "REMOTE_ADDR ") 来取得客户端的IP地址, 但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的I ...
- ASP.NET获取客户端IP地址
public static string GetRealIP() { string ip; try { ...
- asp.net获取客户端IP,Mac
public class GetClientInfo { [DllImport("Iphlpapi.dll")] private static extern int SendARP ...
- (转)【ASP.NET开发】获取客户端IP地址 via C#
[ASP.NET开发]获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己 ...
- ASP.NET获取客户端信息,获取客户端IP等等
山上明月 ASP.NET能知道的东西 获取服务器电脑名: Page.Server.ManchineName 获取用户信息: Page.User 获取客户端电脑名:Page.Request.UserHo ...
随机推荐
- ConcurrentHashMap并不是绝对线程安全的
import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; publi ...
- jersey获取各个参数的总结
service端: @Path("/hello") public class HelloService { @GET @Produces("text/plain" ...
- 提高PHP编码的一些技巧
1.不要使用相对路径 例如 require_once('../../lib/some_class.php'); 该方法有很多缺点: 1)它首先查找指定的php包含路径, 然后查找当前目录 2)如果该脚 ...
- mybatis启动报错Result Maps collection already contains value forxxx
ssm搭建过程中启动tomcat,报错: Cause: java.lang.IllegalArgumentException: Result Maps collection already conta ...
- 奇怪的php问题
<?php echo 999999999999 % 2; ?> 上面的结果居然是-1,不可思议. 999999999999 % 2
- Android开发学习之数据存取
Android系统中提供了一种文件读写的方法,可以将一些数据以文件的形式保存在设备中.比如一些word文档,PDF文档,图片,音频,视频文件等. 使用文件读写方法的步骤: 1.调用Context.op ...
- 卸载linux订阅包
message日志信息: Oct :: oracledb1 rhsmd: In order for Subscription Manager to provide your system with u ...
- sqlserver中将varchar类型转换为int型再进行排序的方法
sql中把varchar类型转换为int型然后进行排序,如果我们数据库的ID设置为varchar型的 在查询的时候order by id的话 如果我们数据库的ID设置为varchar型的 在查询的时候 ...
- 线程模型、pthread 系列函数 和 简单多线程服务器端程序
一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属于1:1模型. (一).N:1用户线程模型 “线程实现”建立在“进程控制”机制之上,由用 ...
- mysql (已解决)Access denied for user 'root'@'localhost' (using password: NO)
找到mysql中的my.ini,在最后一行加入 skip-grant-tables 在“管理工具”-”服务” 中重启mysql 解决问题