You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Ocelot网关的微服务应用中如何获取客户端真实IP?

解决Ocelot网关下Core API获取真实客户端IP的问题

问题原因

Core API收到的请求是Ocelot网关转发的,所以RemoteIpAddress获取到的是网关的IP(本地开发环境就是::1)。需要让网关将客户端真实IP通过请求头传递,再由Core API解析该请求头。

解决方案步骤

1. 配置Ocelot网关转发客户端IP头

在Ocelot的配置文件(ocelot.json)中,添加转发X-Forwarded-For请求头的配置:

方式1:针对单个路由配置

{
  "Routes": [
    {
      // 其他路由配置(如DownstreamPathTemplate、UpstreamPathTemplate等)
      "ForwardHeaders": ["X-Forwarded-For", "X-Forwarded-Proto"]
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "https://your-gateway-domain"
  }
}

方式2:全局配置(所有路由生效)

{
  "GlobalConfiguration": {
    "BaseUrl": "https://your-gateway-domain",
    "MiddlewareOptions": {
      "ForwardHeaders": {
        "ForwardedHeaders": "XForwardedFor,XForwardedProto"
      }
    }
  }
}

2. 配置Core API信任网关代理

在Core API的Program.cs中,配置ForwardedHeadersOptions,让ASP.NET Core信任网关的IP,从而正确解析转发的请求头:

var builder = WebApplication.CreateBuilder(args);

// 配置转发头选项
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    // 添加网关的IP到信任列表,本地开发可添加"::1",生产环境替换为网关真实IP
    options.KnownProxies.Add(IPAddress.Parse("::1"));
    // 指定要解析的转发头类型
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});

// 注册服务
builder.Services.AddScoped<IIdentityService, IdentityService>();
builder.Services.AddHttpContextAccessor();

var app = builder.Build();

// 注意:UseForwardedHeaders必须放在UseAuthentication、UseAuthorization等中间件之前
app.UseForwardedHeaders();

// 其他中间件配置
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

3. 修改Core API获取IP的代码

修改IdentityService,优先从X-Forwarded-For头中获取真实客户端IP:

public class IdentityService : IIdentityService
{
    private readonly IHttpContextAccessor _context; 

    public IdentityService(IHttpContextAccessor context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }
  
    public string GetCleintAdressIP()
    {
        var httpContext = _context.HttpContext;
        if (httpContext == null)
        {
            return "(unknown)";
        }

        // 从X-Forwarded-For头获取真实IP,该头可能包含多个代理IP,第一个为原始客户端IP
        var forwardedFor = httpContext.Request.Headers.XForwardedFor.FirstOrDefault();
        if (!string.IsNullOrWhiteSpace(forwardedFor))
        {
            var ipAddresses = forwardedFor.Split(',', StringSplitOptions.RemoveEmptyEntries);
            return $"({ipAddresses.First().Trim()})";
        }

        // 当没有转发头时,回退到RemoteIpAddress
        var remoteIp = httpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown";
        return $"({remoteIp})";
    }
}

排障思路

  • 检查网关转发配置:确认Ocelot的ForwardHeaders已包含X-Forwarded-For,可通过调试网关或查看请求日志验证头是否被转发。
  • 验证Core API信任配置:确保网关IP已加入KnownProxies,否则ASP.NET Core会忽略转发头(安全机制,防止伪造头)。
  • 检查请求头:用Postman或浏览器开发者工具查看请求发送到Core API时是否携带X-Forwarded-For头,值是否为客户端真实IP。
  • 调试代码:在Core API中打断点,查看Request.Headers.XForwardedFor和Connection.RemoteIpAddress的值,确认转发逻辑是否生效。
  • 生产环境安全:不要将KnownProxies设为*,必须指定信任的网关IP,避免恶意客户端伪造X-Forwarded-For头。

内容的提问来源于stack exchange,提问作者rahim soufiane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:13:17