فهرست منبع

优化 IP 过滤逻辑并调整服务注入格式

在 `ClientIpFilterAttribute.cs` 中:
- 修改 `_whiteIps` 为空时的返回条件格式。
- 更新获取客户端 IP 的逻辑,优先从 `X-Forwarded-For` 和 `X-Real-IP` 请求头中获取 IP 地址。
- 增加对 IPv6 映射到 IPv4 的处理。
- 增加日志记录,记录请求的 IP 地址。
- 增加对以冒号开头的 IP 地址的处理,将冒号替换为空格并去除空格。
- 修改 `_whiteIps` 包含 IP 的判断条件格式。

在 `StartupExtensions.cs` 中:
- 增加 `IdentityConfiguration` 的配置绑定。
- 保留 `SendSmsConfiguration` 的注释。
- 调整服务注入的格式。
- 增加 `ISessionContext` 的键控作用域注入。
- 调整缓存服务的注入格式。
- 修正 `ZiGong` 应用范围下 `AiXingTang` 服务的注入格式。
- 将 `ClientIpFilterAttribute` 的生命周期从单例修改为作用域,并在获取白名单 IP 时过滤掉空值。
xf 3 هفته پیش
والد
کامیت
1f4c70c4ed
2فایلهای تغییر یافته به همراه25 افزوده شده و 13 حذف شده
  1. 14 4
      src/Hotline.Api/Filter/ClientIpFilterAttribute.cs
  2. 11 9
      src/Hotline.Api/StartupExtensions.cs

+ 14 - 4
src/Hotline.Api/Filter/ClientIpFilterAttribute.cs

@@ -16,7 +16,7 @@ namespace Hotline.Api.Filter
 
         public override void OnActionExecuting(ActionExecutingContext context)
         {
-            if(!_whiteIps.Any()) return;
+            if (!_whiteIps.Any()) return;
 
             //var ip = context.HttpContext.Connection.RemoteIpAddress?.ToString();
             //if (ip != null)
@@ -24,11 +24,21 @@ namespace Hotline.Api.Filter
             //    context.HttpContext.Items["ClientIp"] = ip;
             //}
             var ip = context.HttpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault();
-            if(string.IsNullOrEmpty(ip))
+            if (string.IsNullOrEmpty(ip))
                 ip = context.HttpContext.Request.Headers["X-Real-IP"].FirstOrDefault();
 
             if (string.IsNullOrEmpty(ip))
-                ip = context.HttpContext.Connection.RemoteIpAddress?.ToString();
+            {
+                var remoteIp = context.HttpContext.Connection.RemoteIpAddress;
+                if (remoteIp?.IsIPv4MappedToIPv6 ?? false)
+                    remoteIp = remoteIp.MapToIPv4();
+                ip = remoteIp?.ToString();
+            }
+
+            _logger.LogWarning("Request from IP: {RemoteIp}", ip);
+
+            if (ip.StartsWith(':') || ip.StartsWith("::"))
+                ip = ip.Replace(':', ' ').Trim();
 
             if (string.IsNullOrEmpty(ip))
             {
@@ -36,7 +46,7 @@ namespace Hotline.Api.Filter
                 context.Result = new StatusCodeResult(StatusCodes.Status403Forbidden);
             }
 
-            if(!_whiteIps.Contains(ip))
+            if (!_whiteIps.Contains(ip))
             {
                 _logger.LogWarning("Forbidden Request from IP: {RemoteIp}", ip);
                 context.Result = new StatusCodeResult(StatusCodes.Status403Forbidden);

+ 11 - 9
src/Hotline.Api/StartupExtensions.cs

@@ -61,7 +61,7 @@ internal static class StartupExtensions
 #if DEBUG
         builder.WebHost.UseUrls("http://*:50100");
 #endif
-        
+
         services.Configure<IdentityConfiguration>(d => configuration.GetSection(nameof(IdentityConfiguration)).Bind(d));
 
         var appConfigurationSection = configuration.GetRequiredSection(nameof(AppConfiguration));
@@ -74,10 +74,10 @@ internal static class StartupExtensions
         services.Configure<CallCenterConfiguration>(d => callCenterConfigurationSection.Bind(d));
 
         services.Configure<CityBaseConfiguration>(d => configuration.GetSection(nameof(CityBaseConfiguration)).Bind(d));
-		//services.Configure<SendSmsConfiguration>(d => configuration.GetSection("SendSms").Bind(d));
+        //services.Configure<SendSmsConfiguration>(d => configuration.GetSection("SendSms").Bind(d));
 
-		// Add services to the container.
-		services
+        // Add services to the container.
+        services
             .BatchInjectServices(d =>
             {
                 var attr = d.GetCustomAttribute(typeof(InjectionAttribute)) as InjectionAttribute;
@@ -90,11 +90,11 @@ internal static class StartupExtensions
             .AddScoped(typeof(IPasswordHasher<>), typeof(PasswordHasher<>))
             .AddHttpClient()
             ;
-        
+
         services.AddKeyedScoped<ISessionContext, ProvinceSessionContext>(ProvinceSessionContext.Key)
             .AddKeyedScoped<ISessionContext, Police110SessionContext>(Police110SessionContext.Key)
             ;
-        
+
         //cache
         services.AddCache(d =>
         {
@@ -149,7 +149,7 @@ internal static class StartupExtensions
                     .AddKeyedScoped<ISessionContext, ZzptSessionContext>(ZzptSessionContext.Key);
                 break;
             case AppDefaults.AppScope.ZiGong:
-				services.AddAiXingTang(appConfiguration.ZiGong.AiQuality.Url);
+                services.AddAiXingTang(appConfiguration.ZiGong.AiQuality.Url);
                 break;
             case AppDefaults.AppScope.LuZhou:
                 break;
@@ -227,12 +227,14 @@ internal static class StartupExtensions
 
         services.AddScoped<IGuiderSystemService, TiqnQueService>();
 
-        services.AddSingleton<ClientIpFilterAttribute>(sp =>
+        services.AddScoped<ClientIpFilterAttribute>(sp =>
         {
             var loggerFactory = sp.GetService<ILoggerFactory>();
             var logger = loggerFactory.CreateLogger<ClientIpFilterAttribute>();
             var cacheManager = sp.GetService<ISystemSettingCacheManager>();
-            var whiteIps = cacheManager.GetSetting(SettingConstants.WhiteIp).SettingValue;
+            var whiteIps = cacheManager.GetSetting(SettingConstants.WhiteIp).SettingValue
+                .Where(d => !string.IsNullOrEmpty(d))
+                .ToList();
 
             return new ClientIpFilterAttribute(whiteIps, logger);
         });