我在为我的应用程序设置速率限制时遇到了问题。主要思想是启用全局速率限制(影响所有端点),但能够对某些 API 端点禁用它并为它们启用另一个速率限制,因此我们可以对这些端点限制较少。
我们尝试创建两个:全局速率限制中间件和 API 速率限制中间件。两种中间件都可以工作,但特定于 API 的中间件不会覆盖全局中间件。 (总是两者都适用)我怎样才能改变它?
builder.Services.AddRateLimiter(limiterOptions =>
{
limiterOptions.OnRejected = (context, cancellationToken) =>
{
if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter))
{
context.HttpContext.Response.Headers.RetryAfter =
((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo);
}
context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
GetUserEndPoint(context.HttpContext));
return new ValueTask();
};
limiterOptions.AddPolicy(userPolicyName, context =>
{
var username = "anonymous user";
if (context.User.Identity?.IsAuthenticated is true)
{
//await context.GetTokenAsync(JwtBearerDefaults, AuthenticationScheme, "access_token");
username = context.Request.Headers.Authorization!;
}
return RateLimitPartition.GetFixedWindowLimiter(username,
_ => new FixedWindowRateLimiterOptions
{
PermitLimit = myOptions.TokenLimit2,
Window = TimeSpan.FromSeconds(myOptions.Window),
});
});
limiterOptions.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, IPAddress>(context =>
{
var test = context.Request.Host;
IPAddress? remoteIpAddress = context.Connection.RemoteIpAddress;
if (IPAddress.IsLoopback(remoteIpAddress!))
{
return RateLimitPartition.GetSlidingWindowLimiter
(remoteIpAddress!,
_ => new SlidingWindowRateLimiterOptions
{
PermitLimit = myOptions.PermitLimit,
//QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
//QueueLimit = myOptions.QueueLimit,
Window = TimeSpan.FromSeconds(myOptions.Window),
SegmentsPerWindow = myOptions.SegmentsPerWindow
});
}
return RateLimitPartition.GetNoLimiter(IPAddress.Loopback);
});
我在
Rate Limiting middleware
中使用 Asp.net core 7
。
正如文档中提到的:
应用于所有请求的 GlobalLimiter。全局限制器 将首先执行,然后是端点特定的限制器,如果 存在一个。 GlobalLimiter 为每个 IP 地址创建一个分区
您应该注册两个策略并将它们应用到不同的端点