asp.net core程序部署在centos7(下面的解決方案,其他系統都能使用,這里只是我自己部署在centos7),使用服務器jexus進行部署,AppHost模式。
因為請求是由jexus進行了轉發的,所以asp.net zero獲取的ip永遠都是127.0.0.1.。
解決方案:
使用由Jexus作者宇內流雲提供的JwsIntegration替換IISIntegration,它改變默認從請求頭獲取ip的規則,改為由 “X-Original-For”獲取遠程ip(經測試 使用"X-Real-IP"也能獲取)。
JwsIntegration.cs:
/// <summary> /// 用於處理客戶IP地址、端口的HostBuilder中間件 /// </summary> public static class WebHostBuilderJexusExtensions { /// <summary> /// 啟用JexusIntegration中間件 /// </summary> /// <param name="hostBuilder"></param> /// <returns></returns> public static IWebHostBuilder UseJexusIntegration(this IWebHostBuilder hostBuilder) { if (hostBuilder == null) { throw new ArgumentNullException(nameof(hostBuilder)); } // 檢查是否已經加載過了 if (hostBuilder.GetSetting(nameof(UseJexusIntegration)) != null) { return hostBuilder; } // 設置已加載標記,防止重復加載 hostBuilder.UseSetting(nameof(UseJexusIntegration), true.ToString()); // 添加configure處理 hostBuilder.ConfigureServices(services => { services.AddSingleton<IStartupFilter>(new JwsSetupFilter()); }); return hostBuilder; } } class JwsSetupFilter : IStartupFilter { public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next) { return app => { app.UseMiddleware<JexusMiddleware>(); next(app); }; } } class JexusMiddleware { readonly RequestDelegate _next; public JexusMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, IOptions<IISOptions> options) { _next = next; } public async Task Invoke(HttpContext httpContext) { var headers = httpContext.Request.Headers; try { if (headers != null && headers.ContainsKey("X-Original-For")) { var ipaddAdndPort = headers["X-Original-For"].ToArray()[0]; var dot = ipaddAdndPort.IndexOf(":", StringComparison.Ordinal); var ip = ipaddAdndPort; var port = 0; if (dot > 0) { ip = ipaddAdndPort.Substring(0, dot); port = int.Parse(ipaddAdndPort.Substring(dot + 1)); } httpContext.Connection.RemoteIpAddress = System.Net.IPAddress.Parse(ip); if (port != 0) httpContext.Connection.RemotePort = port; } } finally { await _next(httpContext); } } }
使用方法: