nginx反向代理后abp的webapi host如何获取客户端ip?

时间:2023-03-09 09:28:37
nginx反向代理后abp的webapi host如何获取客户端ip?

dotnet core 跨平台是微软伟大的创举,脱离iis后服务器成本都降低了。

问题

这不,采用abp搞了个小项目,部署到centos后发现审计日志里面的ip信息不对。

nginx反向代理后abp的webapi host如何获取客户端ip?

解决

这个问题在.net 4.5下处理过,记得当时是继承 WebClientInfoProvider重写GetClientIpAddress。

将代码拿来后发现dotnet core下报错。

跟进后发现 dotnet core下使用的是 Abp.AspNetCore.Mvc.Auditing下的:HttpContextClientInfoProvider

步骤一

修改代码如下,将其放在 xxx.Web.Core 的Extensions目录:

public class WebClientInfoProviderFix : IClientInfoProvider
{
public string BrowserInfo => GetBrowserInfo(); public string ClientIpAddress => GetClientIpAddress(); public string ComputerName => GetComputerName(); public ILogger Logger { get; set; } private readonly IHttpContextAccessor _httpContextAccessor; private readonly HttpContext _httpContext; /// <summary>
/// Creates a new <see cref="HttpContextClientInfoProvider"/>.
/// </summary>
public WebClientInfoProviderFix(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
_httpContext = httpContextAccessor.HttpContext; Logger = NullLogger.Instance;
} protected virtual string GetBrowserInfo()
{
var httpContext = _httpContextAccessor.HttpContext ?? _httpContext;
return httpContext?.Request?.Headers?["User-Agent"];
} protected virtual string GetClientIpAddress()
{
try
{
var httpContext = _httpContextAccessor.HttpContext ?? _httpContext; var headers = httpContext?.Request.Headers;
if (headers!=null&&headers.ContainsKey("X-Forwarded-For"))
{
httpContext.Connection.RemoteIpAddress = IPAddress.Parse(headers["X-Forwarded-For"].ToString().Split(',', StringSplitOptions.RemoveEmptyEntries)[0]);
}
return httpContext?.Connection?.RemoteIpAddress?.ToString();
}
catch (Exception ex)
{
Logger.Warn(ex.ToString());
}
return null;
} protected virtual string GetComputerName()
{
return null; //TODO: Implement!
}
}

步骤二

然后xxxWebCoreModule.cs中添加如下:

            //jieky@2019-1-24 针对 获取客户端ip异常的处理
Configuration.ReplaceService(typeof(Abp.Auditing.IClientInfoProvider), () =>
{
IocManager.Register<Abp.Auditing.IClientInfoProvider, Extensions.WebClientInfoProviderFix>(Abp.Dependency.DependencyLifeStyle.Transient);
});

步骤三

nginx配置例子

server {
listen 5002;
access_log off;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:5000;
}
}

参考:

ASP.NET Core 搭配 Nginx 的真实IP问题