ASP.NET Core WebApi AspNetCoreRateLimit 限流中间件学习
2021-01-24 05:17
标签:tostring pad conf 匹配 ddr 包含 syntax ane address
AspNetCoreRateLimit介绍: AspNetCoreRateLimit是ASP.NET核心速率限制框架,能够对WebApi,Mvc中控制限流,AspNetCoreRateLimit包包含IpRateLimit中间件和ClientRateLimit中间件,每个中间件都可以为不同的场景设置多个限,该框架的作者是stefanprodan,项目nuget地址是https://github.com/stefanprodan/AspNetCoreRateLimit。 对客户端IP限流控制。 首先nuget安装 Install-Package AspNetCoreRateLimit ,在Startup中Code以下代码,添加服务和注入,其中的配置是什么;注释都有了。 在Configure中配置RateLimit的启动 我们还需要再appsettings.json中写入配置和规则: 如果EnableEndpointRateLimiting设置为false,那么这些限制就全局使用,例如,如果设置每秒5次调用的限制,对任何端口的任何http调用都计入这个限制,反之,如果它是true,那么该限制将应用于{端口}{path}中的每个端点。 如果stackblockedrequest设置为false,则不会将拒绝调用添加到节流阀计数器,如果你要拒绝你必须设置为true; ClientidHeader用于提取白清单的客户端id,如果客户端id在这个里面,就不会应用速率限制。 覆盖特定IP一般规则: IP字段支持IP v4和v6值,我们还需要去定义速率限制规则 规则由端点,期间和限制组成,示例(将所有的端点的速率限制每秒2次呼叫),那么定义如下: 如果在同一端点,例如get/values在一秒中你调用了3次,那么第三次将会被阻止;但是如果说你在同一秒内还调用了Put/values那么不会阻止,因为他们不是在同一端点之中。在期间(Period)中,还有单位 s m h 等. 有的时候我们对拦截有一定的自定义需求的时候,我们可以继承IpRateLimitMiddleware,如以下定义: 行为 当客户端进行HTTP调用时,IpRateLimitMiddleware执行以下操作: 如果请求被阻止,则客户端会收到如下文本响应: 如果请求没有得到速率限制,那么匹配规则中定义的最长周期用于组成X-Rate-Limit标头,这些标头将在响应中注入: 默认情况下,组织了客户端的调用我们都会记录到日志中,那么我们可以使用Microsoft.Extensions.Logging.ILogger,这个就略过了。 我们有的时候需要添加ip规则或者更新速率,如一下所示: 这样呢,你可以将ip限制的规则放到数据库中再推送到缓存中。 ASP.NET Core WebApi AspNetCoreRateLimit 限流中间件学习 标签:tostring pad conf 匹配 ddr 包含 syntax ane address 原文地址:https://www.cnblogs.com/lonelyxmas/p/12052108.html
// This method gets called by the runtime. Use this method to add services to the container.
public
void
ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
//添加appsettings.json
services.AddOptions();
//需要存储速率和ip规则
services.AddMemoryCache();
//加载appsettings.json中的配置项 ,下面三项是加载general,rules
services.Configure
"IpRateLimiting"
));
services.Configure
"IpRateLimitPolicies"
));
//注入计时器和规则
services.AddSingleton
services.AddSingleton
//添加框架服务
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public
void
Configure(IApplicationBuilder app, IHostingEnvironment env,ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection(
"Logging"
));
loggerFactory.AddDebug();
app.UseIpRateLimiting();
if
(env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseMvc();
}
"IpRateLimiting"
: {
"EnableEndpointRateLimiting"
:
false
,
"StackBlockedRequests"
:
false
,
"RealIpHeader"
:
"X-Real-IP"
,
"ClientIdHeader"
:
"X-ClientId"
,
"HttpStatusCode"
: 429,
"IpWhitelist"
: [
"127.0.0.1"
,
"::1/10"
,
"192.168.0.0/24"
],
"EndpointWhitelist"
: [
"get:/api/license"
,
"*:/api/status"
],
"ClientWhitelist"
: [
"dev-id-1"
,
"dev-id-2"
],
"GeneralRules"
: [
{
"Endpoint"
:
"*"
,
"Period"
:
"1s"
,
"Limit"
: 2
},
{
"Endpoint"
:
"*"
,
"Period"
:
"15m"
,
"Limit"
: 100
},
{
"Endpoint"
:
"*"
,
"Period"
:
"12h"
,
"Limit"
: 1000
},
{
"Endpoint"
:
"*"
,
"Period"
:
"7d"
,
"Limit"
: 10000
}
]
}
"IpRateLimitPolicies"
: {
"IpRules"
: [
{
"Ip"
:
"84.247.85.224"
,
"Rules"
: [
{
"Endpoint"
:
"*"
,
"Period"
:
"1s"
,
"Limit"
: 10
},
{
"Endpoint"
:
"*"
,
"Period"
:
"15m"
,
"Limit"
: 200
}
]
},
{
"Ip"
:
"192.168.3.22/25"
,
"Rules"
: [
{
"Endpoint"
:
"*"
,
"Period"
:
"1s"
,
"Limit"
: 5
},
{
"Endpoint"
:
"*"
,
"Period"
:
"15m"
,
"Limit"
: 150
},
{
"Endpoint"
:
"*"
,
"Period"
:
"12h"
,
"Limit"
: 500
}
]
}
]
}
{
"Endpoint": "*",
"Period": "1s",
"Limit": 2
}
public
class
CustomizationLimitMiddleware : IpRateLimitMiddleware
{
private
readonly
IpRateLimitOptions _options;
private
readonly
IIpPolicyStore _ipPolicyStore;
public
CustomizationLimitMiddleware(RequestDelegate next, IOptions
null
) :
base
(next, options, counterStore, policyStore, logger, ipParser)
{
_options = options.Value;
_ipPolicyStore = policyStore;
}
public
override
ClientRequestIdentity SetIdentity(HttpContext httpContext)
{
var
clientId =
"anon"
;
if
(httpContext.Request.Headers.Keys.Contains(_options.ClientIdHeader, StringComparer.CurrentCultureIgnoreCase))
{
clientId = httpContext.Request.Headers[_options.ClientIdHeader].First();
}
return
new
ClientRequestIdentity
{
Path = httpContext.Request.Path.ToString().ToLowerInvariant(),
HttpVerb = httpContext.Request.Method.ToLowerInvariant(),
ClientId = clientId
};
}
}
Status Code: 429
Retry-After: 58
Content: API calls quota exceeded! maximum admitted 2 per 1m.
X-Rate-Limit-Limit: the rate limit period (eg. 1m, 12h, 1d)
X-Rate-Limit-Remaining: number of request remaining
X-Rate-Limit-Reset: UTC date time (ISO 8601) when the limits resets
public
class
IpRateLimitController : Controller
{
private
readonly
IpRateLimitOptions _options;
private
readonly
IIpPolicyStore _ipPolicyStore;
public
IpRateLimitController(IOptions
{
_options = optionsAccessor.Value;
_ipPolicyStore = ipPolicyStore;
}
[HttpGet]
public
IpRateLimitPolicies Get()
{
return
_ipPolicyStore.Get(_options.IpPolicyPrefix);
}
[HttpPost]
public
void
Post()
{
var
pol = _ipPolicyStore.Get(_options.IpPolicyPrefix);
//add
pol.IpRules.Add(
new
IpRateLimitPolicy
{
Ip =
"8.8.4.4"
,
Rules =
new
List
new
RateLimitRule[] {
new
RateLimitRule {
Endpoint =
"*:/api/testupdate"
,
Limit = 100,
Period =
"1d"
}
})
});
//update
_ipPolicyStore.Set(_options.IpPolicyPrefix, pol);
}
}
文章标题:ASP.NET Core WebApi AspNetCoreRateLimit 限流中间件学习
文章链接:http://soscw.com/index.php/essay/46198.html