|
@ -31,6 +31,7 @@ using CK.SCP.Models.Enums; |
|
|
using SCP.Common; |
|
|
using SCP.Common; |
|
|
using System.Drawing.Imaging; |
|
|
using System.Drawing.Imaging; |
|
|
using System.Drawing; |
|
|
using System.Drawing; |
|
|
|
|
|
using System.Net.NetworkInformation; |
|
|
|
|
|
|
|
|
namespace SCP |
|
|
namespace SCP |
|
|
{ |
|
|
{ |
|
@ -1833,5 +1834,116 @@ namespace SCP |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#region 获取反向代理时的客户端的IP地址 getClientIP
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取反向代理时的客户端的IP地址
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>返回客户端真实IP</returns>
|
|
|
|
|
|
private string getClientIP() |
|
|
|
|
|
{ |
|
|
|
|
|
HttpRequest request = HttpContext.Current.Request; |
|
|
|
|
|
|
|
|
|
|
|
string ip = request.Headers.Get("x-forwarded-for"); |
|
|
|
|
|
|
|
|
|
|
|
if (ip == null || ip.Length == 0 || string.Equals("unknown", ip, StringComparison.OrdinalIgnoreCase)) |
|
|
|
|
|
{ |
|
|
|
|
|
ip = request.Headers.Get("Proxy-Client-IP"); |
|
|
|
|
|
} |
|
|
|
|
|
if (ip == null || ip.Length == 0 || string.Equals("unknown", ip, StringComparison.OrdinalIgnoreCase)) |
|
|
|
|
|
{ |
|
|
|
|
|
ip = request.Headers.Get("WL-Proxy-Client-IP"); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
if (ip == null || ip.Length == 0 || string.Equals("unknown", ip, StringComparison.OrdinalIgnoreCase)) |
|
|
|
|
|
{ |
|
|
|
|
|
ip = request.UserHostAddress; |
|
|
|
|
|
} |
|
|
|
|
|
//可能存在如下格式:X-Forwarded-For: client, proxy1, proxy2
|
|
|
|
|
|
int i = 0; |
|
|
|
|
|
if (ip.Contains(", ")) |
|
|
|
|
|
{ |
|
|
|
|
|
//如果存在多个反向代理,获得的IP是一个用逗号分隔的IP集合,取第一个
|
|
|
|
|
|
//X-Forwarded-For: client 第一个
|
|
|
|
|
|
string[] ipaddrs = ip.Split(new string[1] { ", " }, StringSplitOptions.RemoveEmptyEntries); |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < ipaddrs.Length; i++) |
|
|
|
|
|
{ |
|
|
|
|
|
if (ipaddrs[i] != "") |
|
|
|
|
|
{ |
|
|
|
|
|
if (false == IsInnerIP(ipaddrs[i]))//判断是否为内网IP
|
|
|
|
|
|
{ |
|
|
|
|
|
IPAddress realip; |
|
|
|
|
|
if (IPAddress.TryParse(ipaddrs[i], out realip) && ipaddrs[i].Split('.').Length == 4) |
|
|
|
|
|
{//合法IP
|
|
|
|
|
|
return ipaddrs[i]; |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{//非法IP
|
|
|
|
|
|
//IP地址不符合规范
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
ip = ipaddrs[0];//默认取第一个ip地址
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return ip; |
|
|
|
|
|
} |
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region 判断IP地址是否为局域网内网地址
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 判断IP地址是否为内网IP地址
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ipAddress">IP地址字符串</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private bool IsInnerIP(String ipAddress) |
|
|
|
|
|
{ |
|
|
|
|
|
bool isInnerIp = false; |
|
|
|
|
|
ulong ipNum = ip2ulong(ipAddress); |
|
|
|
|
|
/** |
|
|
|
|
|
私有IP:A类 10.0.0.0-10.255.255.255 |
|
|
|
|
|
B类 172.16.0.0-172.31.255.255 |
|
|
|
|
|
C类 192.168.0.0-192.168.255.255 |
|
|
|
|
|
当然,还有127这个网段是环回地址 |
|
|
|
|
|
**/ |
|
|
|
|
|
ulong aBegin = ip2ulong("10.0.0.0"); |
|
|
|
|
|
ulong aEnd = ip2ulong("10.255.255.255"); |
|
|
|
|
|
ulong bBegin = ip2ulong("172.16.0.0"); |
|
|
|
|
|
ulong bEnd = ip2ulong("172.31.255.255"); |
|
|
|
|
|
ulong cBegin = ip2ulong("192.168.0.0"); |
|
|
|
|
|
ulong cEnd = ip2ulong("192.168.255.255"); |
|
|
|
|
|
isInnerIp = IsInner(ipNum, aBegin, aEnd) || IsInner(ipNum, bBegin, bEnd) || IsInner(ipNum, cBegin, cEnd) || ipAddress.Equals("127.0.0.1"); |
|
|
|
|
|
return isInnerIp; |
|
|
|
|
|
} |
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 把IP地址转换为Long型数字
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ipAddress">IP地址字符串</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private ulong ip2ulong(string ipAddress) |
|
|
|
|
|
{ |
|
|
|
|
|
byte[] bytes = IPAddress.Parse(ipAddress).GetAddressBytes(); |
|
|
|
|
|
ulong ret = 0; |
|
|
|
|
|
|
|
|
|
|
|
foreach (byte b in bytes) |
|
|
|
|
|
{ |
|
|
|
|
|
ret <<= 8; |
|
|
|
|
|
ret |= b; |
|
|
|
|
|
} |
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 判断用户IP地址转换为Long型后是否在内网IP地址所在范围
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="userIp"></param>
|
|
|
|
|
|
/// <param name="begin"></param>
|
|
|
|
|
|
/// <param name="end"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private bool IsInner(ulong userIp, ulong begin, ulong end) |
|
|
|
|
|
{ |
|
|
|
|
|
return (userIp >= begin) && (userIp <= end); |
|
|
|
|
|
} |
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |