隐藏

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

发布:2022/7/24 0:23:45作者:管理员 来源:本站 浏览次数:776

前言

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

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

  • 用于检查每个请求的远程 IP 地址的中间件。

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

中间件

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

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

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


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

操作筛选器

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


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

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


  1. services.AddScoped<ClientIpCheckActionFilter>(container =>
  2. {
  3. var loggerFactory = container.GetRequiredService<ILoggerFactory>();
  4. var logger = loggerFactory.CreateLogger<ClientIpCheckActionFilter>();
  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 地址。

总结

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