深圳幻海软件技术有限公司 欢迎您!

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

2023-02-27

前言本篇展示了如何在ASP.NETCore应用程序中设置IP白名单验证的2种方式。你可以使用以下2种方式:用于检查每个请求的远程IP地址的中间件。MVC操作筛选器,用于检查针对特定控制器或操作方法的请求的远程IP地址。中间件Startup.Configure方法将自定义AdminSafeListMi

前言

本篇展示了如何在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"); 
  • 1.

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

public class AdminSafeListMiddleware 

    private readonly RequestDelegate _next; 
    private readonly ILogger<AdminSafeListMiddleware> _logger; 
    private readonly string _safelist; 
 
    public AdminSafeListMiddleware( 
        RequestDelegate next
        ILogger<AdminSafeListMiddleware> logger, 
        string safelist) 
    { 
        _safelist = safelist; 
        _next = next
        _logger = logger; 
    } 
 
    public async Task Invoke(HttpContext context) 
    { 
        if (context.Request.Method != HttpMethod.Get.Method) 
        { 
            var remoteIp = context.Connection.RemoteIpAddress; 
            _logger.LogDebug("Request from Remote IP address: {RemoteIp}", remoteIp); 
 
            string[] ip = _safelist.Split(';'); 
 
            var bytes = remoteIp.GetAddressBytes(); 
            var badIp = true
            foreach (var address in ip) 
            { 
                var testIp = IPAddress.Parse(address); 
                if (testIp.GetAddressBytes().SequenceEqual(bytes)) 
                { 
                    badIp = false
                    break; 
                } 
            } 
 
            if (badIp) 
            { 
                _logger.LogWarning( 
                    "Forbidden Request from Remote IP address: {RemoteIp}", remoteIp); 
                context.Response.StatusCode = StatusCodes.Status403Forbidden; 
                return
            } 
        } 
 
        await _next.Invoke(context); 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.

操作筛选器

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

public class ClientIpCheckActionFilter : ActionFilterAttribute 

    private readonly ILogger _logger; 
    private readonly string _safelist; 
 
    public ClientIpCheckActionFilter(string safelist, ILogger logger) 
    { 
        _safelist = safelist; 
        _logger = logger; 
    } 
 
    public override void OnActionExecuting(ActionExecutingContext context) 
    { 
        var remoteIp = context.HttpContext.Connection.RemoteIpAddress; 
        _logger.LogDebug("Remote IpAddress: {RemoteIp}", remoteIp); 
        var ip = _safelist.Split(';'); 
        var badIp = true
 
        if (remoteIp.IsIPv4MappedToIPv6) 
        { 
            remoteIp = remoteIp.MapToIPv4(); 
        } 
 
        foreach (var address in ip) 
        { 
            var testIp = IPAddress.Parse(address); 
 
            if (testIp.Equals(remoteIp)) 
            { 
                badIp = false
                break; 
            } 
        } 
 
        if (badIp) 
        { 
            _logger.LogWarning("Forbidden Request from IP: {RemoteIp}", remoteIp); 
            context.Result = new StatusCodeResult(StatusCodes.Status403Forbidden); 
            return
        } 
 
        base.OnActionExecuting(context); 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.

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

services.AddScoped<ClientIpCheckActionFilter>(container => 

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

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

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

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

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

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

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

总结

 

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