ASP.NET Core WebApi AspNetCoreRateLimit 限流中间件学习

原文:ASP.NET Core WebApi AspNetCoreRateLimit 限流中间件学习

AspNetCoreRateLimit介绍:

AspNetCoreRateLimit是ASP.NET核心速率限制框架,能够对WebApi,Mvc中控制限流,AspNetCoreRateLimit包包含IpRateLimit中间件和ClientRateLimit中间件,每个中间件都可以为不同的场景设置多个限,该框架的作者是stefanprodan,项目nuget地址是https://github.com/stefanprodan/AspNetCoreRateLimit

对客户端IP限流控制。

首先nuget安装 Install-Package AspNetCoreRateLimit ,在Startup中Code以下代码,添加服务和注入,其中的配置是什么;注释都有了。

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// 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<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));

            services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies"));

            //注入计时器和规则

            services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();

            services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();

            //添加框架服务

            services.AddMvc();

        }

在Configure中配置RateLimit的启动

?


1

2

3

4

5

6

7

8

9

10

// 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();

        }

我们还需要再appsettings.json中写入配置和规则:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

"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

    }

  ]

}

如果EnableEndpointRateLimiting设置为false,那么这些限制就全局使用,例如,如果设置每秒5次调用的限制,对任何端口的任何http调用都计入这个限制,反之,如果它是true,那么该限制将应用于{端口}{path}中的每个端点。

如果stackblockedrequest设置为false,则不会将拒绝调用添加到节流阀计数器,如果你要拒绝你必须设置为true;

ClientidHeader用于提取白清单的客户端id,如果客户端id在这个里面,就不会应用速率限制。

覆盖特定IP一般规则:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

"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值,我们还需要去定义速率限制规则

规则由端点,期间和限制组成,示例(将所有的端点的速率限制每秒2次呼叫),那么定义如下:

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

如果在同一端点,例如get/values在一秒中你调用了3次,那么第三次将会被阻止;但是如果说你在同一秒内还调用了Put/values那么不会阻止,因为他们不是在同一端点之中。在期间(Period)中,还有单位 s m h 等.

有的时候我们对拦截有一定的自定义需求的时候,我们可以继承IpRateLimitMiddleware,如以下定义:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

public class CustomizationLimitMiddleware : IpRateLimitMiddleware

    {

        private readonly IpRateLimitOptions _options;

        private readonly IIpPolicyStore _ipPolicyStore;

        public CustomizationLimitMiddleware(RequestDelegate next, IOptions<IpRateLimitOptions> options, IRateLimitCounterStore counterStore, IIpPolicyStore policyStore, ILogger<IpRateLimitMiddleware> logger, IIpAddressParser ipParser = 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

            };

        }

    }

行为

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

  • 从请求体中获取IP,客户端IP,Http信息,和一些URL,如果需要修改自己的提取逻辑,可以覆盖IpRateLimitMiddleware.SetIdentity。
  • 在白名单中搜索IP,客户端ID和URL,如果有匹配则不执行任何操作
  • 在IP规则中搜索匹配项,所有适用的规则按期间分组,对于每个期间使用最严格的规则
  • 在匹配的一般规则中搜索,如果匹配的一般规则具有IP规则中不存在的定义时间段,则也使用此一般规则
  • 对于每个匹配规则,速率限制计数器递增,如果计数器值大于规则限制,则请求被阻止

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

?


1

2

3

Status Code: 429

Retry-After: 58

Content: API calls quota exceeded! maximum admitted 2 per 1m.

如果请求没有得到速率限制,那么匹配规则中定义的最长周期用于组成X-Rate-Limit标头,这些标头将在响应中注入:

?


1

2

3

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

默认情况下,组织了客户端的调用我们都会记录到日志中,那么我们可以使用Microsoft.Extensions.Logging.ILogger,这个就略过了。

我们有的时候需要添加ip规则或者更新速率,如一下所示:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

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);

          //add

        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" }

            })

        });

          //update

        _ipPolicyStore.Set(_options.IpPolicyPrefix, pol);

    }

}

这样呢,你可以将ip限制的规则放到数据库中再推送到缓存中。

原文地址:https://www.cnblogs.com/lonelyxmas/p/12052108.html

时间: 2024-11-10 00:59:30

ASP.NET Core WebApi AspNetCoreRateLimit 限流中间件学习的相关文章

【Dnc.Api.Throttle】适用于.Net Core WebApi接口限流框架

Dnc.Api.Throttle    适用于Dot Net Core的WebApi接口限流框架 使用Dnc.Api.Throttle可以使您轻松实现WebApi接口的限流管理.Dnc.Api.Throttle支持IP.用户身份.Request Header.Request QueryString等多种限流策略,支持黑名单和白名单功能,支持全局拦截和单独Api拦截. Dnc.Api.Throttle暂时只支持Redis作为缓存和存储库,后续会进行扩展. 开始使用 安装Dnc.Api.Thrott

Asp.net Core WebApi 使用Swagger做帮助文档,并且自定义Swagger的UI

WebApi写好之后,在线帮助文档以及能够在线调试的工具是专业化的表现,而Swagger毫无疑问是做Docs的最佳工具,自动生成每个Controller的接口说明,自动将参数解析成json,并且能够在线调试. 那么要讲Swagger应用到Asp.net Core中需要哪些步骤,填多少坑呢? 安装Swagger到项目 { "dependencies": { "Swashbuckle": "6.0.0-beta902", ........ 或者直接通

Asp.Net Core WebApi学习笔记(四)-- Middleware

Asp.Net Core WebApi学习笔记(四)-- Middleware 本文记录了Asp.Net管道模型和Asp.Net Core的Middleware模型的对比,并在上一篇的基础上增加Middleware功能支持. 在演示Middleware功能之前,先要了解一下Asp.Net管道模型发生了什么样的变化. 第一部分:管道模型 1. Asp.Net管道 在之前的Asp.Net里,主要的管道模型流程如下图所示: 请求进入Asp.Net工作进程后,由进程创建HttpWorkRequest对象

ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了

引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者的心情.或者详细点,或者简单点.那么有没有一种快速有效的方法来构建api说明文档呢?答案是肯定的, Swagger就是最受欢迎的REST APIs文档生成工具之一! 为什么使用Swagger作为REST APIs文档生成工具 Swagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学

ASP.NET Core WebApi使用Swagger生成api

引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者的心情.或者详细点,或者简单点.那么有没有一种快速有效的方法来构建api说明文档呢?答案是肯定的, Swagger就是最受欢迎的REST APIs文档生成工具之一! 为什么使用Swagger作为REST APIs文档生成工具 Swagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学

ASP.NET CORE WEBAPI文件下载

最近要使用ASP.NET CORE WEBAPI用来下载文件,使用的.NET CORE 3.1.考虑如下场景: 文件是程序生成的. 文件应该能兼容各种格式. 浏览器可以感知进行下载. 准备 经过简单的调研,得到以下结论. ASP.NET CORE 提供FileResult这种类型的ActionResult,可以直接返回文件结果,不需要直接处理HttpResponse. 通过Stream可以直接返回文件流供浏览器下载. FileStreamResult是FileResult的具体实现,返回值应该是

Asp.net core WebApi 使用Swagger生成帮助页实例

最近我们团队一直进行.net core的转型,web开发向着前后端分离的技术架构演进,我们后台主要是采用了asp.net core webapi来进行开发,开始每次调试以及与前端人员的沟通上都存在这效率低下的问题,一次在看微软asp.net core官方文档的时候,发现了swagger这个好东西.然后在实际的项目中引入了该技术.我们开发人员测试自己写的api的过程大大得到了简化,前端人员也可以根据我们提供的swagger help pages 自己进行一些前端代码的测试,大大提高了前后端的开发效

ASP.NET Core WebAPI 开发-新建WebAPI项目 转

转 http://www.cnblogs.com/linezero/p/5497472.html ASP.NET Core WebAPI 开发-新建WebAPI项目 ASP.NET Core WebAPI 开发-新建WebAPI项目, ASP.NET Core 1.0 RC2 即将发布,我们现在来学习一下 ASP.NET Core WebAPI开发. 网上已经有泄露的VS2015 Tooling,需要VS2015 Update 2. .NET Core 1.0.0 RC2 SDK Preview

Asp.net core WebApi 使用Swagger生成帮助页

最近我们团队一直进行.net core的转型,web开发向着前后端分离的技术架构演进,我们后台主要是采用了asp.net core webapi来进行开发,开始每次调试以及与前端人员的沟通上都存在这效率低下的问题,一次在看微软asp.net core官方文档的时候,发现了swagger这个好东西.然后在实际的项目中引入了该技术.我们开发人员测试自己写的api的过程大大得到了简化,前端人员也可以根据我们提供的swagger help pages 自己进行一些前端代码的测试,大大提高了前后端的开发效