当使用CDN服务时,客户端的原始IP地址通常会被CDN的IP地址替代。以下是几种在C#中获取原始客户端IP地址的方法:
大多数CDN服务(如Cloudflare、Akamai等)会在请求头中添加原始IP信息:
public string GetClientIpAddress(HttpRequest request)
{
// 常见的CDN传递原始IP的头部
var headersToCheck = new[]
{
"CF-Connecting-IP", // Cloudflare
"X-Forwarded-For", // 通用代理/负载均衡
"X-Real-IP", // Nginx代理
"HTTP_CLIENT_IP", // 其他代理
"HTTP_X_FORWARDED_FOR", // 其他代理
"HTTP_X_FORWARDED", // 其他代理
"HTTP_X_CLUSTER_CLIENT_IP", // 其他代理
"HTTP_FORWARDED_FOR", // 其他代理
"HTTP_FORWARDED" // 其他代理
};
foreach (var header in headersToCheck)
{
if (request.Headers.TryGetValue(header, out var ipAddress))
{
// X-Forwarded-For可能包含多个IP(代理链)
if (header == "X-Forwarded-For" && ipAddress.ToString().Contains(","))
{
return ipAddress.ToString().Split(',').First().Trim();
}
return ipAddress.ToString();
}
}
// 如果没有找到特定头部,回退到远程IP地址
return request.HttpContext.Connection.RemoteIpAddress?.ToString();
}
可以创建一个中间件来处理IP地址:
public class RealIpMiddleware
{
private readonly RequestDelegate _next;
public RealIpMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
var ipAddress = GetClientIpAddress(context.Request);
context.Items["ClientRealIp"] = ipAddress;
await _next(context);
}
private string GetClientIpAddress(HttpRequest request)
{
// 同上GetClientIpAddress方法
}
}
然后在Startup.cs中注册:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<RealIpMiddleware>();
// 其他中间件...
}
public string GetCloudflareIpAddress(HttpRequest request)
{
if (request.Headers.TryGetValue("CF-Connecting-IP", out var ipAddress))
{
return ipAddress.ToString();
}
return request.HttpContext.Connection.RemoteIpAddress?.ToString();
}
安全性:不要完全信任这些头部,因为它们可以被伪造。确保只信任来自你已知和信任的CDN/IP的请求。
多个代理:X-Forwarded-For
可能包含多个IP地址(代理链),通常第一个IP是原始客户端IP。
配置CDN:确保你的CDN已配置为转发原始IP地址。例如在Cloudflare中,确保你的服务器在Cloudflare的IP范围内。
IPv6支持:确保你的代码能正确处理IPv6地址。
日志记录:考虑记录原始IP和代理IP,以便调试和安全审计。
通过以上方法,你应该能够在C#应用程序中可靠地获取通过CDN访问的客户端原始IP地址。