.Net Core结合AspNetCoreRateLimit实现限流

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介:

.Net Core结合AspNetCoreRateLimit实现限流

前言
相信使用过WebApiThrottle的童鞋对AspNetCoreRateLimit应该不陌生,AspNetCoreRateLimit是一个ASP.NET Core速率限制的解决方案,旨在控制客户端根据IP地址或客户端ID向Web API或MVC应用发出的请求的速率。AspNetCoreRateLimit包含一个IpRateLimitMiddleware和ClientRateLimitMiddleware,每个中间件可以根据不同的场景配置限制允许IP或客户端,自定义这些限制策略,也可以将限制策略应用在每​​个API URL或具体的HTTP Method上。

实践
起初是因为新做的项目中,有天查询日志发现,对外的几个公共接口经常被“恶意”调用,考虑到接口安全性问题,增加限流策略。

AspNetCoreRateLimit GayHub:https://github.com/stefanprodan/AspNetCoreRateLimit

根据IP进行限流
通过nuget安装AspNetCoreRateLimit,当前版本是3.0.5,因为实际项目中用的都是分布式缓存,在这里不用内存存储,而是结合Redis进行使用,内存存储直接参考官方的Wiki就可以了。

Install-Package AspNetCoreRateLimit

Install-Package Microsoft.Extensions.Caching.Redis
在Startup.ConfigureServices中将服务和其他依赖注入

public void ConfigureServices(IServiceCollection services)

    {
        #region MVC
        services.AddMvc(
          options =>
          {
              options.UseCentralRoutePrefix(new RouteAttribute("api/"));
          }
          ).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        #endregion

        services.AddDistributedRedisCache(options =>
        {
            options.Configuration = "127.0.0.1:6379,password=123456,connectTimeout=5000,syncTimeout=10000"; 
            options.InstanceName = "WebRatelimit";
        }); 
        //加载配置
        services.AddOptions();
        //从appsettings.json获取相应配置
        services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
        
        //注入计数器和规则存储
        services.AddSingleton<IIpPolicyStore, DistributedCacheIpPolicyStore>();
        services.AddSingleton<IRateLimitCounterStore, DistributedCacheRateLimitCounterStore>();
        
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        //配置(计数器密钥生成器)
        services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
    }

在Startup.Configure启用

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }
        //启用限流,需在UseMvc前面
        app.UseIpRateLimiting();
        app.UseMvc();
    }

为了不影响appsettings.json的美观吧,可以新建一个RateLimitConfig.json,并Program中启动加载中增加

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>().ConfigureAppConfiguration((host,config)=> 
            {
                config.AddJsonFile($"RateLimitConfig.json", optional: true, reloadOnChange: true);
            });

RateLimitConfig.json 配置如下:

{
"IpRateLimiting": {

//false则全局将应用限制,并且仅应用具有作为端点的规则* 。 true则限制将应用于每个端点,如{HTTP_Verb}{PATH}
"EnableEndpointRateLimiting": true,
//false则拒绝的API调用不会添加到调用次数计数器上
"StackBlockedRequests": false,
"RealIpHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 200,
"QuotaExceededResponse": {
  "Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\",\"data\":null}}",
  "ContentType": "application/json",
  "StatusCode": 200
},
"IpWhitelist": [ ],
"EndpointWhitelist": [],
"ClientWhitelist": [],
"GeneralRules": [
  {
    "Endpoint": "*:/api/values/test",
    "Period": "5s",
    "Limit": 3
  }
]

}
}

重要配置说明:

       QuotaExceededResponse 是自定义返回的内容,所以必须设置HttpStatusCode和StatusCode为200。

GeneralRules是具体的策略,根据不同需求配置不同端点即可, Period的单位可以是s, m, h, d,Limint是单位时间内的允许访问的次数;

IpWhitelist是IP白名单,本地调试或者UAT环境,可以加入相应的IP,略过策略的限制;

       EndpointWhitelist是端点白名单,如果全局配置了访问策略,设置端点白名单相当于IP白名单一样,略过策略的限制;

其他配置项请参考Wiki:https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/IpRateLimitMiddleware#setup

Fiddler开始测试
测试接口:http://127.0.0.1:5000/api/values/Test

    [HttpGet]
    public object test()
    {
        return "ok";
    }

调用结果:

调用次数和剩余调用次数在Head可以看到,(吃我一个链接:https://www.cnblogs.com/EminemJK/p/12720691.html

如果调用超过策略后,调用失败,返回我们自定义的内容

在Redis客户端可以看到策略的一些情况,

 其他
通常在项目中,Authorization授权是少不了了,加入限流后,在被限流的接口调用后,限流拦截器使得跨域策略失效,故重写拦截器中间件,继承IpRateLimitMiddleware 即可:

public class IPLimitMiddleware : IpRateLimitMiddleware
{
    public IPLimitMiddleware(RequestDelegate next, IOptions<IpRateLimitOptions> options, IRateLimitCounterStore counterStore, IIpPolicyStore policyStore, IRateLimitConfiguration config, ILogger<IpRateLimitMiddleware> logger)
        : base(next, options, counterStore, policyStore, config, logger)
    {
    }

    public override Task ReturnQuotaExceededResponse(HttpContext httpContext, RateLimitRule rule, string retryAfter)
    {
        httpContext.Response.Headers.Append("Access-Control-Allow-Origin", "*");
        return base.ReturnQuotaExceededResponse(httpContext, rule, retryAfter);
    }
}

然后修改Startup.Configure,

    //启用限流,需在UseMvc前面
    //app.UseIpRateLimiting();
    app.UseMiddleware<IPLimitMiddleware>();
    app.UseMvc();

特别需要注意的坑是,在其他文章的教程中,他们会写成:

    app.UseMiddleware<IPLimitMiddleware>().UseIpRateLimiting();//错误的演示 https://www.cnblogs.com/EminemJK/p/12720691.html

这些写你测试的时候会发现,

X-Rate-Limit-Remaining 递减量会变成2,也不是递减1,举栗子,配置如下:

    "Endpoint": "*:/api/values/test",
    "Period": "3s",
    "Limit": 1

表示3秒内可以访问的次数是1一次,当发生调用的时候会直接返回被限制的提示,而不能正常访问接口。

最后
AspNetCoreRateLimit还可以根据客户端ID进行配置策略,具体可以看一下官方的Wiki吧。

作者:EminemJK(山治先生)
出处:https://www.cnblogs.com/EminemJK/

相关文章
|
1月前
|
开发框架 .NET C#
ASP.NET Core Blazor 路由配置和导航
大家好,我是码农刚子。本文系统介绍Blazor单页应用的路由机制,涵盖基础配置、路由参数、编程式导航及高级功能。通过@page指令定义路由,支持参数约束、可选参数与通配符捕获,结合NavigationManager实现页面跳转与参数传递,并演示用户管理、产品展示等典型场景,全面掌握Blazor路由从入门到实战的完整方案。
214 6
|
11月前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
286 5
|
存储 开发框架 JSON
ASP.NET Core OData 9 正式发布
【10月更文挑战第8天】Microsoft 在 2024 年 8 月 30 日宣布推出 ASP.NET Core OData 9,此版本与 .NET 8 的 OData 库保持一致,改进了数据编码以符合 OData 规范,并放弃了对旧版 .NET Framework 的支持,仅支持 .NET 8 及更高版本。新版本引入了更快的 JSON 编写器 `System.Text.UTF8JsonWriter`,优化了内存使用和序列化速度。
266 0
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
258 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
11月前
|
开发框架 算法 中间件
ASP.NET Core 中的速率限制中间件
在ASP.NET Core中,速率限制中间件用于控制客户端请求速率,防止服务器过载并提高安全性。通过`AddRateLimiter`注册服务,并配置不同策略如固定窗口、滑动窗口、令牌桶和并发限制。这些策略可在全局、控制器或动作级别应用,支持自定义响应处理。使用中间件`UseRateLimiter`启用限流功能,并可通过属性禁用特定控制器或动作的限流。这有助于有效保护API免受滥用和过载。 欢迎关注我的公众号:Net分享 (239字符)
262 1
|
11月前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
324 3
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
205 0
|
11月前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
332 5
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
436 0
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
228 7

热门文章

最新文章

下一篇
oss云网关配置