StartUp.cs代碼
public void ConfigureServices(IServiceCollection services) { // needed to load configuration from appsettings.json services.AddOptions(); // needed to store rate limit counters and ip rules services.AddMemoryCache(); //load general configuration from appsettings.json services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting")); //load ip rules from appsettings.json services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies")); // inject counter and rules stores services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>(); services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>(); // Add framework services. services.AddMvc(); // https://github.com/aspnet/Hosting/issues/793 // the IHttpContextAccessor service is not registered by default. // the clientId/clientIp resolvers use it. services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); // configuration (resolvers, counter key builders) services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>(); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseIpRateLimiting(); //if (env.IsDevelopment()) // app.UseDeveloperExceptionPage(); app.UseMvc(); }
IPRateLimiting應該在其他中間件之前注冊, 否則API請求計算可能不正確。
如果您對應用程序進行負載平衡,則需要使用IDistributedCache
Redis或SQLServer,以便所有的kestrel實例都具有相同的速率限制存儲。您應該像這樣注入分布式存儲,而不是使用MemoryCache:
配置和一般規則appsettings.json:
"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": 1 }, { "Endpoint": "*", "Period": "15m", "Limit": 100 }, { "Endpoint": "*", "Period": "12h", "Limit": 1000 }, { "Endpoint": "*", "Period": "7d", "Limit": 10000 } ] }
如果EnableEndpointRateLimiting
設置為false
則全局將應用限制,並且僅應用具有作為端點的規則*
。例如,如果您設置每秒5次調用的限制,則對任何端點的任何HTTP調用都將計入該限制。
如果EnableEndpointRateLimiting
設置為true
,則限制將應用於每個端點,如{HTTP_Verb}{PATH}
。例如,如果您為*:/api/values
客戶端設置每秒5個呼叫的限制,則可以GET /api/values
每秒呼叫5次,但也可以呼叫5次PUT /api/values
。
如果StackBlockedRequests
設置為false
,拒絕的API調用不會添加到調用次數計數器上。比如: 如果客戶端每秒發出3個請求並且您設置了每秒一個調用的限制,則每分鍾或每天計數器等其他限制將僅記錄第一個調用,即成功的API調用。如果您希望被拒絕的API調用計入其他時間的顯示(分鍾,小時等),則必須設置StackBlockedRequests
為true
。
在RealIpHeader
使用時,你的Kestrel 服務器背后是一個反向代理,如果你的代理服務器使用不同的頁眉然后提取客戶端IP X-Real-IP
使用此選項來設置它。
將ClientIdHeader
被用於提取白名單的客戶端ID。如果此標頭中存在客戶端ID並且與ClientWhitelist中指定的值匹配,則不應用速率限制。
覆蓋特定IP appsettings.json的一般規則:
"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 } ] } ] }
IP字段支持IP v4和v6值以及范圍,如 "192.168.0.0/24", "fe80::/10" 或 "192.168.0.0-192.168.0.255"。