ASP.NET Core 获取客户端 IP 地址的处理方法

在基于 ASP.NET Core 的应用中,准确获取客户端的 IP 地址是常见需求,尤其是在有反向代理服务器(如 Nginx、Apache 或 Azure Application Gateway)的情况下,需要正确配置才能获取到实际的客户端 IP。

一、标准获取客户端 IP 的方法

在 ASP.NET Core 中,可以通过 HttpContext.Connection.RemoteIpAddress 获取客户端 IP 地址:

public IActionResult GetClientIp()
{
    var clientIp = HttpContext.Connection.RemoteIpAddress?.ToString();
    return Ok(clientIp);
}

但是在有反向代理的情况下,这个方法通常会返回代理服务器的 IP,而非真实客户端的 IP。

二、使用 X-Forwarded-For 头获取真实客户端 IP

当应用部署在反向代理服务器后,代理通常会将真实客户端 IP 写入 X-Forwarded-For 请求头中。

1. 启用 ForwardedHeaders 中间件

ASP.NET Core 提供了 ForwardedHeadersMiddleware 来解析 X-Forwarded-For 和 X-Forwarded-Proto 头。需要在 Startup 或 Program 文件中启用。

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// 配置中间件以处理转发的头部
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,

    // 信任所有代理服务器
    ForwardLimit = null, // 不限制转发层数
    KnownNetworks = { }, // 清空默认信任的网络范围
    KnownProxies = { }   // 清空默认信任的代理 IP
});

app.MapGet("/client-ip", (HttpContext context) =>
{
    var clientIp = context.Connection.RemoteIpAddress?.ToString();
    var forwardedIp = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
    return$"Client IP: {clientIp}, Forwarded IP: {forwardedIp}";
});

app.Run();

2. 配置反向代理

确保反向代理正确地设置了 X-Forwarded-For 头。

  • Nginx 配置示例
location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://localhost:5000;
}
  • Apache 配置示例
ProxyPass / http://localhost:5000/
ProxyPassReverse / http://localhost:5000/
RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
RequestHeader add X-Forwarded-For %{REMOTE_ADDR}e

三、常见问题及解决方案

1. 未启用 ForwardedHeaders 中间件

如果未启用 UseForwardedHeaders,即使反向代理正确配置了 X-Forwarded-For,应用仍然无法读取真实 IP。

2. 信任的代理服务器配置不当

默认情况下,ASP.NET Core 仅信任本地主机。如果需要信任所有代理服务器,可以清空 KnownNetworks 和 KnownProxies,并设置 ForwardLimit 为 null

3. 多级代理的处理

如果请求经过多个代理服务器,X-Forwarded-For 中会包含以逗号分隔的多个 IP 地址,最左侧的 IP 通常是客户端的真实 IP。

var forwardedHeader = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
var clientIp = forwardedHeader?.Split(',')[0].Trim();

四、使用中间件封装获取 IP 的逻辑

为了便于复用,可以创建一个中间件封装获取客户端真实 IP 的逻辑:

public classClientIpMiddleware
{
    privatereadonly RequestDelegate _next;

    public ClientIpMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var forwardedIp = context.Request.Headers["X-Forwarded-For"].FirstOrDefault()?.Split(',')[0].Trim();
        var clientIp = forwardedIp ?? context.Connection.RemoteIpAddress?.ToString();

        context.Items["ClientIp"] = clientIp;

        await _next(context);
    }
}

// 注册中间件
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseMiddleware<ClientIpMiddleware>();

app.MapGet("/client-ip", (HttpContext context) =>
{
    return context.Items["ClientIp"]?.ToString() ?? "Unknown";
});

app.Run();

五、总结

  1. 获取客户端 IPHttpContext.Connection.RemoteIpAddress 是基础,但需要处理代理情况。
  2. 使用中间件UseForwardedHeaders 解析 X-Forwarded-For
  3. 反向代理配置:确保代理服务器正确设置了转发头。
  4. 多级代理支持:解析 X-Forwarded-For 中的多个 IP 地址。
  5. 信任所有代理:通过配置 ForwardLimit 和清空默认信任的范围实现。

通过以上方法,可以在任何部署环境中正确获取客户端的真实 IP 地址。

posted @   跟着阿笨一起玩.NET  阅读(113)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2021-02-04 SQL Server数据库高级进阶之事务实战演练
2021-02-04 C#如何正确运用异步编程技术
2021-02-04 SQL Server数据库高级进阶之锁实战演练
2020-02-04 .NET Core基于SQL Server数据库主从同步实现读写分离实战演练
2013-02-04 将要被社会淘汰的8种人
点击右上角即可分享
微信分享提示