C#获取真实IP地址(IP转为长整形、判断是否内网IP的方法)
作者:junjie 时间:2022-01-31 08:50:06
今天查看登录日志,发现http_x_forwarded_for获取到的ip地址有些是内网ip地址,有些则是公网和内网ip地址一起获取到,用逗号分隔开,日志截图如下:
之前获取ip地址的C#代码如下:
/// <summary>
/// C#获取客户端真实IP地址
/// </summary>
/// <returns></returns>
public static string GetIP()
{
string ip = HttpContext.Current.Request.ServerVariables["http_x_forwarded_for"];
if (UserCheck.IsNull(ip)) ip = HttpContext.Current.Request.ServerVariables["remote_addr"];
return ip;
}
看来http_x_forwarded_for应该是被其他软件或者ISP修改过了,导致http_x_forwarded_for得不到真实的代理ip地址。之前登陆日志是要判断ip地址是否在允许的ip段内的,这样导致无法登陆系统。最后修改代码如下,增加判断是否为内网或者私有地址,是否符合ipv4的地址规格,不符合还是使用remote_addr来获取客户端的ip地址。
比较安全的获取真实地址的实现代码:
/// <summary>
/// C#将IP地址转为长整形
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public static long IpToNumber(string ip)
{
string[] arr = ip.Split('.');
return 256 * 256 * 256 * long.Parse(arr[0]) + 256 * 256 * long.Parse(arr[1]) + 256 * long.Parse(arr[2]) + long.Parse(arr[3]);
}
/// <summary>
/// C#判断IP地址是否为私有/内网ip地址
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public static bool IsPrivateIp(string ip)
{
long ABegin = IpToNumber("10.0.0.0"), AEnd = IpToNumber("10.255.255.255"),//A类私有IP地址
BBegin = IpToNumber("172.16.0.0"), BEnd = IpToNumber("172.31.255.255"),//'B类私有IP地址
CBegin = IpToNumber("192.168.0.0"), CEnd = IpToNumber("192.168.255.255"),//'C类私有IP地址
IpNum = IpToNumber(ip);
return (ABegin <= IpNum && IpNum <= AEnd) || (BBegin <= IpNum && IpNum <= BEnd) || (CBegin <= IpNum && IpNum <= CEnd);
}
/// <summary>
/// C#获取真实IP地址
/// </summary>
/// <returns></returns>
public static string GetIP()
{
string ip = HttpContext.Current.Request.ServerVariables["http_x_forwarded_for"];
if (UserCheck.IsNull(ip)) ip = HttpContext.Current.Request.ServerVariables["remote_addr"];
else//代理ip地址有内容,判断是否符合ipv4地址或者是否为内网地址
{
ip = ip.Trim().Replace(" ", "");
if (!Regex.IsMatch(ip, @"^\d+(\.\d+){3}$") || IsPrivateIp(ip))
ip = HttpContext.Current.Request.ServerVariables["remote_addr"];//不符合规则或者内网/私有地址使用remote_addr代替
}
return ip;
}
2014-07-02更新:原来是 cdn加速的问题,cdn加速后,由于先判断http_x_forwarded_for,http_x_forwarded_for是随便可以伪造的,放置任何内容的,所以下图出现的ip地址中会有内网地址或者出现2个ip地址的问题。所以获取http_x_forwarded_for内容时需要 split下获取第一个项。
标签:C#,IP地址
0
投稿
猜你喜欢
Springboot整合redis实现发布订阅功能介绍步骤
2021-11-23 16:42:26
JAVA读取文件夹大小的几种方法实例
2021-05-24 21:01:53
Java Maven依赖传递,可选依赖,排除依赖详解
2022-06-09 14:24:14
使用SpringBoot开发Restful服务实现增删改查功能
2023-01-20 05:17:29
Java使用DualPivotQuicksort排序
2022-05-22 20:58:12
Java日常练习题,每天进步一点点(7)
2023-11-27 00:34:58
Android Studio多渠道打包的配置方法
2023-06-15 23:19:48
详解SpringBoot项目的创建与单元测试
2021-06-17 05:13:17
javaweb Servlet开发总结(二)
2023-10-31 11:51:48
Mybatis配置解析看这一篇就够了
2023-05-15 22:42:12
java实现图书检索系统
2023-08-18 20:08:50
C++对string进行大小写转换操作方法
2023-11-03 04:32:59
java easyUI实现自定义网格视图实例代码
2022-05-16 23:52:54
Java泛型的简单实例
2023-11-27 01:03:38
Javacsv实现Java读写csv文件
2022-02-16 01:10:15
Java泛型的使用限制实例分析
2023-05-07 20:14:52
SpringBoot自定义MessageConverter与内容协商管理器contentNegotiationManager详解
2023-11-28 11:35:54
java数据结构算法稀疏数组示例详解
2021-09-30 11:47:28
Android中通过样式来去除app的头及界面全屏(备忘)的实现方法
2023-07-30 00:03:23
maven中profile的使用
2022-03-31 10:43:53