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

Asp.Net Core安全防护-客户端IP白名单限制
最新回答
诗雨伊意

2023-05-11 05:32:48

在ASP.NET Core中实现客户端IP白名单限制,可以通过中间件或操作筛选器两种方式实现。以下是具体实现方法及注意事项:

一、中间件实现方式
  1. 核心逻辑在Startup.Configure中添加自定义中间件,检查请求IP是否在白名单内:

    app.UseMiddleware<AdminSafeListMiddleware>("127.0.0.1;192.168.1.5;::1");
  2. 中间件代码要点

    跳过GET请求验证(context.Request.Method != HttpMethod.Get.Method)

    通过RemoteIpAddress获取客户端IP

    将白名单字符串分割为IP数组进行匹配

    未匹配时返回403 Forbidden

  3. IPv6处理使用GetAddressBytes()进行字节级比较,兼容IPv4和IPv6格式(如::1表示IPv6的localhost)。

二、操作筛选器实现方式
  1. 适用场景针对特定控制器或Action的IP限制,通过[ServiceFilter]属性应用:

    [ServiceFilter(typeof(ClientIpCheckActionFilter))]public class AdminController : Controller
  2. 筛选器代码要点

    继承ActionFilterAttribute

    在OnActionExecuting中验证IP

    处理IPv4映射到IPv6的情况(IsIPv4MappedToIPv6)

    直接设置context.Result终止请求

  3. 依赖注入配置在Startup.ConfigureServices中注册:

    services.AddScoped<ClientIpCheckActionFilter>(provider => { var logger = provider.GetService<ILogger<ClientIpCheckActionFilter>>(); return new ClientIpCheckActionFilter("127.0.0.1;192.168.1.5", logger);});
三、关键注意事项
  1. IP获取准确性

    反向代理场景需配置ForwardedHeadersMiddleware:

    app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto});

    通过context.Connection.RemoteIpAddress获取原始客户端IP

  2. 黑名单改造建议将白名单逻辑取反即可:

    // 中间件示例修改if (ip.Contains(remoteIp.ToString())) { context.Response.StatusCode = 403; return;}
  3. 性能优化

    将白名单IP缓存为HashSet<IPAddress>提升查找效率

    避免在每次请求时解析字符串

  4. 日志记录建议记录以下信息:

    拦截事件(LogWarning级别)

    客户端IP和请求路径

    允许列表内容(调试时使用LogDebug)

四、完整示例代码// 中间件优化版public class IpRestrictionMiddleware { private readonly RequestDelegate _next; private readonly HashSet<IPAddress> _allowedIPs; public IpRestrictionMiddleware(RequestDelegate next, string ipList) { _next = next; _allowedIPs = new HashSet<IPAddress>( ipList.Split(';').Select(IPAddress.Parse) ); } public async Task Invoke(HttpContext context) { var remoteIp = context.Connection.RemoteIpAddress; if (remoteIp != null && !_allowedIPs.Contains(remoteIp)) { context.Response.StatusCode = 403; return; } await _next(); }}五、测试建议
  1. 使用Postman或curl测试不同IP的访问权限
  2. 验证IPv6地址(如curl -g "http://[::1]:5000/api/admin")
  3. 检查日志输出是否符合预期

通过以上两种方式,可以灵活实现基于IP的安全控制。中间件适合全局限制,操作筛选器则适合细粒度控制。在生产环境中建议结合两者使用,并确保正确处理代理服务器场景下的IP获取问题。