速率限制中间件AspNetCoreRateLimit

AspNetCoreRateLimit

AspNetCoreRateLimit 是一种 ASP.NET Core 速率限制解决方案,旨在控制客户端可以根据 IP 地址或客户端 ID 向 Web API 或 MVC 应用发出的请求速率。AspNetCoreRateLimit 包包含一个 IpRateLimitMiddleware 和一个 ClientRateLimitMiddleware,对于每个中间件,你可以为不同的场景设置多个限制,例如允许 IP 或客户端在每秒、15 分钟等时间间隔内进行最大调用次数。您可以定义这些限制以解决对 API 发出的所有请求,也可以将限制范围限定为每个 API URL 或 HTTP 谓词和路径。

设置

NuGet 安装:NuGet install

Install-Package AspNetCoreRateLimit

Install-Package AspNetCoreRateLimit.Redis

Startup.cs代码

public void ConfigureServices(IServiceCollection services)
{// needed to load configuration from appsettings.jsonservices.AddOptions();// needed to store rate limit counters and ip rulesservices.AddMemoryCache();//load general configuration from appsettings.jsonservices.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));//load ip rules from appsettings.jsonservices.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies"));// inject counter and rules storesservices.AddInMemoryRateLimiting();//services.AddDistributedRateLimiting<AsyncKeyLockProcessingStrategy>();//services.AddDistributedRateLimiting<RedisProcessingStrategy>();//services.AddRedisRateLimiting();// Add framework services.services.AddMvc();// configuration (resolvers, counter key builders)services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
}public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{app.UseIpRateLimiting();app.UseMvc();
}

您应该在任何其他组件之前注册中间件。

如果对应用进行负载均衡,则需要与 Redis 或 SQLServer 一起使用,以便所有 kestrel 实例都具有相同的速率限制存储。 您应该像这样注入分布式存储,而不是内存中的存储:IDistributedCache

// inject counter and rules distributed cache stores
services.AddSingleton<IIpPolicyStore, DistributedCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore,DistributedCacheRateLimitCounterStore>();

配置和一般规则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": 2},{"Endpoint": "*","Period": "15m","Limit": 100},{"Endpoint": "*","Period": "12h","Limit": 1000},{"Endpoint": "*","Period": "7d","Limit": 10000}]}

如果设置为,则限制将全局应用,并且仅应用具有终结点的规则。例如,如果设置了每秒 5 次调用的限制,则对任何终结点的任何 HTTP 调用都将计入该限制。EnableEndpointRateLimitingfalse*

如果设置为 ,则限制将应用于每个端点,如 中所示。例如,如果设置为每秒 5 次调用的限制,则客户端可以每秒调用 5 次,但也可以调用 5 次。EnableEndpointRateLimitingtrue{HTTP_Verb}{PATH}*:/api/valuesGET /api/valuesPUT /api/values

如果设置为 ,则拒绝的呼叫不会添加到限制计数器中。如果客户端每秒发出 3 个请求,并且您设置了每秒 <> 个呼叫的限制,则其他限制(如每分钟或每天计数器)将仅记录第一个呼叫,即未被阻止的呼叫。如果您希望被拒绝的请求计入其他限制,则必须设置为 。StackBlockedRequestsfalseStackBlockedRequeststrue

当您的 Kestrel 服务器位于反向代理后面时,用于提取客户端 IP,如果您的代理使用不同的标头,则使用此选项进行设置。RealIpHeaderX-Real-IP

用于提取用于白名单的客户端 ID。如果此标头中存在客户端 ID,并且与 ClientWhitelist 中指定的值匹配,则不应用速率限制。ClientIdHeader

覆盖特定 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”。

如果在 appsettings.json 配置文件中定义了静态速率策略,则需要在应用程序启动时为它们设定种子:

public static async Task Main(string[] args)
{IWebHost webHost = CreateWebHostBuilder(args).Build();using (var scope = webHost.Services.CreateScope()){// get the IpPolicyStore instancevar ipPolicyStore = scope.ServiceProvider.GetRequiredService<IIpPolicyStore>();// seed IP data from appsettingsawait ipPolicyStore.SeedAsync();}await webHost.RunAsync();
}

定义速率限制规则

规则由终结点、周期和限制组成。

端点格式为 ,您可以使用 asterix 符号来定位任何 HTTP 谓词。{HTTP_Verb}:{PATH}

周期格式为 ,可以使用以下周期类型之一:。{INT}{PERIOD_TYPE}s, m, h, d

限制格式为 。{LONG}

示例

将所有终端节点的速率限制为每秒 2 次调用:

通配符:

{"Endpoint": "*","Period": "1s","Limit": 2
}

正则表达式:

{"Endpoint": ".+","Period": "1s","Limit": 2
}

如果在同一秒内从同一 IP 对 api/values 进行 3 次 GET 调用,则最后一次调用将被阻止。但是,如果在同一秒钟内您也调用了 PUT api/values,则请求将通过,因为它是不同的端点。启用终结点速率限制后,每个呼叫都会根据 .{HTTP_Verb}{PATH}

将任何 HTTP Verb 的调用限制为每 5 分钟 15 次调用:/api/values

通配符:

{"Endpoint": "*:/api/values","Period": "15m","Limit": 5
}

正则表达式:

{"Endpoint": ":/api/values","Period": "15m","Limit": 5
}

将 GET 呼叫的速率限制为每小时 5 次调用:/api/values

{"Endpoint": "get:/api/values","Period": "1h","Limit": 5
}

将 POST 或 PUT 呼叫的速率限制为每小时 5 次呼叫:/api/values

{"Endpoint": "((post)|(put)):/api/values","Period": "1h","Limit": 5
}

如果在一小时内从同一个 IP 对 api/values 进行 6 次 GET 调用,则最后一次调用将被阻止。但是,如果在同一小时内您也调用 GET api/values/1,则请求将通过,因为它是一个不同的终结点。

行为

当客户端进行 HTTP 调用时,执行以下操作:IpRateLimitMiddleware : RateLimitMiddleware<IpRateLimitProcessor>

  • 从请求对象中提取 IP、客户端 ID、HTTP 谓词和 URL,如果要实现自己的提取逻辑,可以覆盖该方法或实现自定义 IP/客户端解析器:IpRateLimitMiddleware.ResolveIdentity
public class CustomRateLimitConfiguration : RateLimitConfiguration
{protected override void RegisterResolvers(){base.RegisterResolvers();ClientResolvers.Add(new ClientQueryStringResolveContributor(HttpContextAccessor, ClientRateLimitOptions.ClientIdHeader));}
}
  • 在白名单中搜索 IP、客户端 ID 和 URL,如果匹配,则不执行任何操作。

  • 在 IP 规则中搜索匹配项,所有适用的规则都按时间段分组,每个时间段使用限制性最强的规则。

  • 在常规规则中搜索匹配项,如果匹配的常规规则具有 IP 规则中不存在的已定义时间段,则也会使用此常规规则。

  • 对于每个匹配的规则,速率限制计数器都会递增,如果计数器值大于规则限制,则请求将被阻止。

如果请求被阻止,则客户端会收到如下文本响应:

<span style="color:#1f2328"><span style="background-color:#ffffff"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>Status Code: 429
Retry-After: 58
Content: API calls quota exceeded! maximum admitted 2 per 1m.
</code></span></span></span></span>

您可以通过更改这些选项来自定义响应,如果要实现自己的响应,可以覆盖 .标头值以秒为单位表示。HttpStatusCodeQuotaExceededMessageIpRateLimitMiddleware.ReturnQuotaExceededResponseRetry-After

如果请求未受到速率限制,则使用匹配规则中定义的最长周期来编写 X-Rate-Limit 标头,这些标头将注入响应中:

<span style="color:#1f2328"><span style="background-color:#ffffff"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>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
</code></span></span></span></span>

客户端可以像这样解析:X-Rate-Limit-Reset

<span style="color:#1f2328"><span style="background-color:#ffffff"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>DateTime resetDate = DateTime.ParseExact(resetHeader, "o", DateTimeFormatInfo.InvariantInfo);
</code></span></span></span></span>

可以通过将选项设置为 in appsettings.json 来禁用 X-Rate-Limit 和 Retry-After 标头。DisableRateLimitHeaderstrue

默认情况下,使用 记录被阻止的请求,如果要实现自己的日志记录,可以覆盖 . 当请求受到速率限制时,默认记录器会发出以下信息:Microsoft.Extensions.Logging.ILoggerIpRateLimitMiddleware.LogBlockedRequest

<span style="color:#1f2328"><span style="background-color:#ffffff"><span style="color:var(--fgColor-default, var(--color-fg-default))"><span style="background-color:var(--bgColor-muted, var(--color-canvas-subtle))"><code>info: AspNetCoreRateLimit.IpRateLimitMiddleware[0]Request get:/api/values from IP 84.247.85.224 has been blocked, quota 2/1m exceeded by 3. Blocked by rule *:/api/value, TraceIdentifier 0HKTLISQQVV9D.
</code></span></span></span></span>

在运行时更新速率限制

在应用程序启动时,定义的 IP 速率限制规则由或取决于您使用的缓存提供程序类型加载到缓存中。您可以访问控制器内部的 Ip 策略存储并修改 IP 规则,如下所示:appsettings.jsonMemoryCacheClientPolicyStoreDistributedCacheIpPolicyStore

public class IpRateLimitController : Controller
{private readonly IpRateLimitOptions _options;private readonly IIpPolicyStore _ipPolicyStore;public IpRateLimitController(IOptions<IpRateLimitOptions> optionsAccessor, IIpPolicyStore ipPolicyStore){_options = optionsAccessor.Value;_ipPolicyStore = ipPolicyStore;}[HttpGet]public IpRateLimitPolicies Get(){return _ipPolicyStore.Get(_options.IpPolicyPrefix);}[HttpPost]public void Post(){var pol = _ipPolicyStore.Get(_options.IpPolicyPrefix);pol.IpRules.Add(new IpRateLimitPolicy{Ip = "8.8.4.4",Rules = new List<RateLimitRule>(new RateLimitRule[] {new RateLimitRule {Endpoint = "*:/api/testupdate",Limit = 100,Period = "1d" }})});_ipPolicyStore.Set(_options.IpPolicyPrefix, pol);}
}

这样,您可以将 IP 速率限制存储在数据库中,并在每次应用程序启动后将其推送到缓存中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/23621.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LLama2源码分析——Rotary Position Embedding分析

参考&#xff1a;一文看懂 LLaMA 中的旋转式位置编码&#xff08;Rotary Position Embedding&#xff09; 原理推导参考自上文&#xff0c;以下结合huggingface代码分析公式计算过程 1 旋转角度计算 计算公式如下&#xff0c;其中d为词嵌入维度&#xff0c;这部分和论文原文…

STM32 音乐播放器之音频入门实验(pwm、dac、.wav、.mp3)

1.pwm实现简易电子琴实验 1.改变PWM频率&#xff0c;输出不同音调 2.改变占空比&#xff0c;调节音量大小 3.按键弹奏&#xff0c;支持按按键录取弹奏音 4.播放:中高低音&#xff1b;录取音&#xff1b;指定歌曲 5.支持按上一首&#xff0c;下一首&#xff0c;调弹奏速度&#…

Docker Desktop下载安装

Window下使用Docker推荐使用Docker Desktop; Docker Desktop是一款适用于Windows操作系统的桌面应用&#xff0c;它为开发人员提供了一个界面化操作Docker的环境&#xff0c;以便在本地环境中轻松创建、构建和运行Docker容器: Windows系统下Docker Desktop的安装 官网下载安装…

英国树莓派五大天王和你相约上海国际嵌入式展!

6月12日-14日 上海世博展览馆3号馆 H3馆 237展位 树莓派(Raspberry Pi),这个曾经让全球掀起"创客热潮"的小型单板电脑,如今已经成为嵌入式行业不可或缺的一员。作为行业先驱,树莓派基金会正携手团队,亮相2024年6月12日至6月14日在上海举办的 Embedded World上海国…

如何更精准定位你的Facebook广告受众?

Facebook广告成为吸引目标受众、推广产品和服务的重要工具之一。然而&#xff0c;要让广告取得更好的效果&#xff0c;关键在于精准定位受众。本文将介绍如何通过策略和技巧更精确地定位Facebook广告受众&#xff0c;提高广告投放的效果和转化率。 一、精准受众定位重要吗&…

值传递过程中的开销

当处理很大的字符串时&#xff0c;按值传递和按引用传递的区别会更加明显。让我们详细介绍一下字符串的拷贝过程以及占用的内存情况。 字符串按值传递 当你按值传递一个大字符串时&#xff0c;会发生以下过程&#xff1a; 创建临时副本&#xff1a; 在函数调用时&#xff0c;…

完全背包(从二维数组到一维滚动数组)

完全背包 二维dp数组完全背包1. 确定dp数组以及下标的含义2. 确定递推公式3. dp数组如何初始化4. 确定遍历顺序5. 举例推导dp数组完整代码: 一维滚动dp数组完全背包1.确定dp数组以及下标的含义2. 确定递推公式3. dp数组如何初始化4. 确定遍历顺序5. 举例推导dp数组完整代码&…

填充每个节点的下一个右侧节点Ⅱ-力扣

本题如果使用BFS去层序遍历&#xff0c;代码和 填充每个节点的下一个右侧节点 题没有任何区别。但是使用已经建立好的next链表去做&#xff0c;则需要考虑到next指向的节点子节点是否为空的可能。 class Solution { public:Node* connect(Node* root) {if(root nullptr){retu…

城镇污水处理设施运维服务认证

初次申请认证时需提交的文件/资料 1、通用文件/资料(证明文件复印件需签字盖公章) ☐ 营业执照复印件、统一社会信用代码/组织机构代码证复印件 ☐ 增值税一般纳税人资格证复印件&#xff0c;或其他增值税一般纳税人资格认定文件复印件 ☐ 资质 或 许可证 复印件&#x…

RT-Thread

RT-Thread RT-Thread 版权属于上海睿赛德电子科技有限公司&#xff0c;于 2006年 1月首次发布&#xff0c;初始版 本号为0.1.0&#xff0c;经过 10来年的发展&#xff0c;如今主版本号已经升级到3.0&#xff0c;累计开发者达到数百万&#xff0c; 在各行各业产品中装机量达到了…

C++ 并发编程指南(5)线程状态及切换

文章目录 一、多线程状态及切换1、线程状态2、状态切换 前言&#xff1a; C中的线程状态及切换是操作系统和C线程库&#xff08;如POSIX线程或C11及之后的<thread>库&#xff09;共同管理的。线程的状态和切换是多线程编程中的重要概念&#xff0c;下面将简要介绍C线程的…

大数据的数据变换与价值提炼

大数据的数据变换与价值提炼是指将原始的大数据进行分析和处理&#xff0c;从中提取出有用的信息和洞察&#xff0c;并转化为可以支持决策和创新的价值。这个过程通常包括以下几个步骤&#xff1a; 数据清洗和整理&#xff1a;原始的大数据通常会包含大量的噪音和冗余信息&…

大模型SFT

简介 supervised fine-tuning的缩写&#xff0c;即有监督的微调。如应用到一个新的场景&#xff0c;就可以使用SFT 开发流程 设计prompt选取llm模型制作数据集&#xff0c;子任务1k就可以了。内容要丰富。风格格式统一&#xff1b;尽量不加入新知识SFT微调 疑问 SFT很难学…

【Linux取经路】守护进程

文章目录 一、前台进程和后台进程二、Linux 的进程间关系三、setsid——将当前进程设置为守护进程四、daemon——设置为守护进程五、结语 一、前台进程和后台进程 Linux 中每一次用户登录都是一个 session&#xff0c;一个 session 中只能有一个前台进程在运行&#xff0c;键盘…

国产工业级实时数据库

项目功能描述 Mars数据库的核心功能在于其能够高效地处理来自工业现场的大量传感器数据。它通过简化的可视化配置&#xff0c;允许用户轻松接入各种传感器&#xff0c;并进行数据记录和逻辑处理。Mars数据库在单机模式下支持高达120万个传感器信号的接入&#xff0c;而其分布式…

Python Excel 指定内容修改

需求描述 在处理Excel 自动化时,财务部门经常有一个繁琐的场景,需要读取分发的Excel文件内容复制到汇总Excel文件对应的单元格内,如下图所示: 这种需求可以延申为,财务同事制作一个模板,将模板发送给各员工,财务同事需收取邮件将员工填写的excel文件下载到本机,再类似…

Java Web学习笔记15——DOM对象

DOM&#xff1a; 概念&#xff1a;Document Object Model&#xff1a; 文档对象模型 将标记语言的各个组成部分封装为对应的对象&#xff1a; Document: 整个文档对象 Element&#xff1a;元素对象 Attribute&#xff1a; 属性对象 Text&#xff1a;文本对象 Comment&a…

c++11 constexpr关键字

constexpr 是 C11 引入的一个关键字&#xff0c;它允许在编译时计算表达式的值&#xff0c;并将这些值存储在程序的常量部分中。这意味着 constexpr 变量和函数可以在编译时进行求值&#xff0c;从而避免了运行时的开销。 constexpr变量 constexpr 变量必须在编译时初始化&am…

如何使用ChatGPT写出爆款自媒体短视频文案

一、引言 自媒体时代&#xff0c;短视频的爆款文案往往能决定内容的传播效果。在众多工具中&#xff0c;ChatGPT以其强大的语言模型和多样化的应用场景&#xff0c;成为创作者的得力助手。今天我将分享如何使用ChatGPT来撰写引人注意的短视频文案&#xff0c;助你的内容一飞冲…

【Linux取经路】信号的发送与保存

文章目录 一、重新理解发送信号二、信号的保存、阻塞信号的概念三、信号集操作函数3.1 sigprocmask3.2 sigpending 四、阻塞信号代码验证五、结语 一、重新理解发送信号 进程通过位图来实现对普通信号&#xff08;1-31号信号&#xff09;的保存&#xff0c;该位图保存在进程的…