Asp.Net Core安全防护-客户端IP白名单限制

时间:2022-04-21 21:59:14

Asp.Net Core安全防护-客户端IP白名单限制

前言

本篇展示了如何在ASP.NET Core应用程序中设置IP白名单验证的2种方式。

你可以使用以下2种方式:

  • 用于检查每个请求的远程 IP 地址的中间件。
  • MVC 操作筛选器,用于检查针对特定控制器或操作方法的请求的远程 IP 地址。

中间件

Startup.Configure方法将自定义 AdminSafeListMiddleware 中间件类型添加到应用的请求管道。 使用 .NET Core 配置提供程序检索到该安全,并将其作为构造函数参数进行传递。

  1. app.UseMiddleware<AdminSafeListMiddleware>("127.0.0.1;192.168.1.5;::1"); 

中间件将字符串分析为数组,并在数组中搜索远程 IP 地址。 如果找不到远程 IP 地址,中间件将返回 HTTP 403 禁止访问。 对于 HTTP GET 请求,将跳过此验证过程。

  1. public class AdminSafeListMiddleware 
  2.     private readonly RequestDelegate _next; 
  3.     private readonly ILogger<AdminSafeListMiddleware> _logger; 
  4.     private readonly string _safelist; 
  5.  
  6.     public AdminSafeListMiddleware( 
  7.         RequestDelegate next
  8.         ILogger<AdminSafeListMiddleware> logger, 
  9.         string safelist) 
  10.     { 
  11.         _safelist = safelist; 
  12.         _next = next
  13.         _logger = logger; 
  14.     } 
  15.  
  16.     public async Task Invoke(HttpContext context) 
  17.     { 
  18.         if (context.Request.Method != HttpMethod.Get.Method) 
  19.         { 
  20.             var remoteIp = context.Connection.RemoteIpAddress; 
  21.             _logger.LogDebug("Request from Remote IP address: {RemoteIp}", remoteIp); 
  22.  
  23.             string[] ip = _safelist.Split(';'); 
  24.  
  25.             var bytes = remoteIp.GetAddressBytes(); 
  26.             var badIp = true
  27.             foreach (var address in ip) 
  28.             { 
  29.                 var testIp = IPAddress.Parse(address); 
  30.                 if (testIp.GetAddressBytes().SequenceEqual(bytes)) 
  31.                 { 
  32.                     badIp = false
  33.                     break; 
  34.                 } 
  35.             } 
  36.  
  37.             if (badIp) 
  38.             { 
  39.                 _logger.LogWarning( 
  40.                     "Forbidden Request from Remote IP address: {RemoteIp}", remoteIp); 
  41.                 context.Response.StatusCode = StatusCodes.Status403Forbidden; 
  42.                 return
  43.             } 
  44.         } 
  45.  
  46.         await _next.Invoke(context); 
  47.     } 

操作筛选器

如果需要针对特定 MVC 控制器或操作方法的安全安全访问控制,请使用操作筛选器。 例如:。

  1. public class ClientIpCheckActionFilter : ActionFilterAttribute 
  2.     private readonly ILogger _logger; 
  3.     private readonly string _safelist; 
  4.  
  5.     public ClientIpCheckActionFilter(string safelist, ILogger logger) 
  6.     { 
  7.         _safelist = safelist; 
  8.         _logger = logger; 
  9.     } 
  10.  
  11.     public override void OnActionExecuting(ActionExecutingContext context) 
  12.     { 
  13.         var remoteIp = context.HttpContext.Connection.RemoteIpAddress; 
  14.         _logger.LogDebug("Remote IpAddress: {RemoteIp}", remoteIp); 
  15.         var ip = _safelist.Split(';'); 
  16.         var badIp = true
  17.  
  18.         if (remoteIp.IsIPv4MappedToIPv6) 
  19.         { 
  20.             remoteIp = remoteIp.MapToIPv4(); 
  21.         } 
  22.  
  23.         foreach (var address in ip) 
  24.         { 
  25.             var testIp = IPAddress.Parse(address); 
  26.  
  27.             if (testIp.Equals(remoteIp)) 
  28.             { 
  29.                 badIp = false
  30.                 break; 
  31.             } 
  32.         } 
  33.  
  34.         if (badIp) 
  35.         { 
  36.             _logger.LogWarning("Forbidden Request from IP: {RemoteIp}", remoteIp); 
  37.             context.Result = new StatusCodeResult(StatusCodes.Status403Forbidden); 
  38.             return
  39.         } 
  40.  
  41.         base.OnActionExecuting(context); 
  42.     } 

在中 Startup.ConfigureServices ,将操作筛选器添加到 MVC 筛选器集合。 在下面的示例中, ClientIpCheckActionFilter 添加了一个操作筛选器。 安全日志和控制台记录器实例作为构造函数参数进行传递。

  1. services.AddScoped<ClientIpCheckActionFilter>(container => 
  2.     var loggerFactory = container.GetRequiredService<ILoggerFactory>(); 
  3.     var logger = loggerFactory.CreateLogger<ClientIpCheckActionFilter>(); 
  4.  
  5.     return new ClientIpCheckActionFilter( 
  6.         "127.0.0.1;192.168.1.5;::1", logger); 
  7. }); 

然后,可以将操作筛选器应用到具有 [ServiceFilter] 属性的控制器或操作方法:

  1. [ServiceFilter(typeof(ClientIpCheckActionFilter))] 
  2. [HttpGet] 
  3. public IEnumerable<string> Get() 

在示例应用中,操作筛选器将应用于控制器的 Get 操作方法。 当你通过发送来测试应用程序时:

HTTP GET 请求,该 [ServiceFilter] 属性验证客户端 IP 地址。 如果允许访问 Get 操作方法,则 "操作筛选器" 和 "操作" 方法将生成以下控制台输出的变体:

  1. dbug: ClientIpSafelistComponents.Filters.ClientIpCheckActionFilter[0] 
  2.       Remote IpAddress: ::1 
  3. dbug: ClientIpAspNetCore.Controllers.ValuesController[0] 
  4.       successful HTTP GET 

除 GET 之外的 HTTP 请求谓词将 AdminSafeListMiddleware 验证客户端 IP 地址。

总结

该案例完全可以改造成黑名单拦截。

原文链接:https://mp.weixin.qq.com/s/DXDCHQcZ1azLTU0TEswjwQ