在IIS部署环境下如何获取调用客户端的真实IP?
解决IIS部署下获取客户端真实IP的问题
问题根源
当ASP.NET应用部署在IIS后,若存在反向代理(如IIS ARR、Nginx等),请求会先经过代理服务器再转发至应用。此时HttpContext.Connection.RemoteIpAddress默认获取的是代理服务器的IP,而非客户端真实IP。真实客户端IP会被代理服务器放入X-Forwarded-For或X-Real-IP请求头中,但需正确配置才能让应用识别。
解决方案
1. 配置代理服务器传递真实IP头
确保前端代理服务器(包括IIS自身的ARR模块)转发请求时添加X-Forwarded-For和X-Real-IP头:
- 若使用IIS ARR:打开IIS管理器 → 进入ARR代理设置 → 勾选启用X-Forwarded-For选项。
- 若使用其他代理(如Nginx):在代理配置中添加规则(示例):
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Real-IP $remote_addr;
2. 配置ASP.NET应用信任代理
在应用中启用ForwardedHeaders中间件,让应用识别代理传递的真实IP头,自动将RemoteIpAddress替换为客户端真实IP。
在.NET 6+的Program.cs中添加以下配置(需放在其他中间件之前):
var builder = WebApplication.CreateBuilder(args); // 配置ForwardedHeaders选项 builder.Services.Configure<ForwardedHeadersOptions>(options => { // 开启转发X-Forwarded-For和X-Forwarded-Proto头 options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; // 添加信任的代理服务器IP/网段,比如IIS服务器的内网IP或环回地址 options.KnownProxies.Add(IPAddress.Parse("127.0.0.1")); // 若代理在特定网段,可添加网段(示例:192.168.1.0/24) // options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("192.168.1.0"), 24)); }); var app = builder.Build(); // 必须在其他中间件(如UseRouting、UseAuthorization)之前调用 app.UseForwardedHeaders(); // 其他应用配置... app.Run();
3. 优化真实IP获取方法
启用ForwardedHeaders后,HttpContext.Connection.RemoteIpAddress会自动返回客户端真实IP。若需兼容无代理场景,可使用以下改进后的方法,同时处理多层代理的情况:
private string GetClientIpAddress(HttpContext context) { // 启用ForwardedHeaders后,优先使用RemoteIpAddress var remoteIp = context.Connection.RemoteIpAddress?.ToString(); if (!string.IsNullOrEmpty(remoteIp)) { // 转换IPv6环回地址为IPv4格式 return remoteIp == "::1" ? "127.0.0.1" : remoteIp; } // 处理X-Forwarded-For(多层代理时格式为"客户端IP, 代理1IP, 代理2IP",取第一个) var xForwardedFor = context.Request.Headers["X-Forwarded-For"].FirstOrDefault(); if (!string.IsNullOrEmpty(xForwardedFor)) { return xForwardedFor.Split(',').First().Trim(); } // 最后 fallback到X-Real-IP return context.Request.Headers["X-Real-IP"].FirstOrDefault() ?? "unknown"; }
4. 验证配置
部署修改后的应用后,使用不同网络环境的客户端(如手机流量、另一台局域网设备)访问,检查获取到的IP是否与客户端公网/内网IP一致。也可通过浏览器开发者工具查看请求头中是否包含X-Forwarded-For字段。
内容的提问来源于stack exchange,提问作者Sidhant Priyadarshan Biswal
相关产品推荐
相关产品推荐

