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问题