.NET 7 ASP.NET Core Web API基于IP的限流实现优化问询
.NET 7 原生IP限流实现方案(适配Azure Windows应用服务)
先解决核心问题:RemoteIpAddress为空
部署在Azure App Service时,请求会经过平台反向代理,默认情况下RemoteIpAddress拿到的是代理服务器IP,甚至可能为空。首先要配置转发头,确保获取真实客户端IP:
builder.Services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; // 清空默认已知网络/代理,Azure环境下平台会保障转发头合法性 options.KnownNetworks.Clear(); options.KnownProxies.Clear(); }); // 该中间件需放在UseRouting之前 app.UseForwardedHeaders();
实现IP维度的限流逻辑
使用.NET 7原生Microsoft.AspNetCore.RateLimiting库,通过自定义PartitionedRateLimiter按IP地址分区限流,同时处理RemoteIpAddress为空的情况,消除CS8602警告:
builder.Services.AddRateLimiter(options => { // 全局IP限流策略 options.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(context => { // IP为空时用兜底标识,避免空引用 var clientIp = context.Connection.RemoteIpAddress?.ToString() ?? "fallback-ip"; // 示例规则:1分钟最多10次请求,排队上限2个 return RateLimitPartition.GetFixedWindowLimiter( partitionKey: clientIp, factory: _ => new FixedWindowRateLimiterOptions { PermitLimit = 10, Window = TimeSpan.FromMinutes(1), QueueProcessingOrder = QueueProcessingOrder.OldestFirst, QueueLimit = 2 }); }); // 自定义限流拒绝响应 options.OnRejected = async (context, cancellationToken) => { context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests; await context.HttpContext.Response.WriteAsync("请求过于频繁,请稍后重试。", cancellationToken); }; }); // 启用限流中间件,需放在MapControllers之前 app.UseRateLimiter(); app.MapControllers();
可选:针对特定接口限流
若无需全局限流,可定义命名策略,用特性标记目标控制器/动作:
builder.Services.AddRateLimiter(options => { options.AddPolicy("IpRateLimit", context => { var clientIp = context.Connection.RemoteIpAddress?.ToString() ?? "fallback-ip"; return RateLimitPartition.GetFixedWindowLimiter(clientIp, _ => new FixedWindowRateLimiterOptions { PermitLimit = 5, Window = TimeSpan.FromSeconds(30) }); }); }); // 在控制器中应用策略 [ApiController] [Route("api/[controller]")] [EnableRateLimiting("IpRateLimit")] public class UserController : ControllerBase { // 接口逻辑... }
关键细节
- Azure环境适配:必须配置
ForwardedHeaders,否则无法获取用户真实IP,限流会失效。 - CS8602警告处理:通过
??给空IP设置兜底标识,或提前做空值判断返回无限制器,按需选择即可。 - SPA同部署场景:SPA从用户浏览器发起API请求,仍需获取真实用户IP,转发头配置不可省略。
内容的提问来源于stack exchange,提问作者Qiuzman
相关产品推荐
相关产品推荐

