← l-artikli kollha

.NET

L-Implimentazzjoni tar-Rate Limiting fl-APIs ta’ ASP.NET Core

Tgħallem kif tipproteġi l-APIs ta’ ASP.NET Core bil-middleware integrat għar-rate limiting, named policies, client partitions, responses HTTP 429, u għażliet prattiċi ta’ konfigurazzjoni.

Pipeline ta’ requests ta’ API ASP.NET Core b’middleware għar-rate limiting li jirrifjuta requests żejda b’HTTP 429

Ir-rate limiting jikkontrolla kemm requests taċċetta API matul perjodu speċifiku. Huwa utli għal APIs pubbliċi, endpoints ta’ awtentikazzjoni, operazzjonijiet għaljin, u integrazzjonijiet fejn client wieħed ma għandux jikkonsma r-riżorsi kollha disponibbli.

ASP.NET Core jipprovdi middleware integrat għar-rate limiting b’algoritmi fixed window, sliding window, token bucket, u concurrency. Il-policies jistgħu jkunu globali jew jiġu assenjati biss lil endpoints magħżula. (learn.microsoft.com)

Għaliex ir-rate limiting huwa importanti

Rate limiter jista’ jgħin lil API:

  • tipprevjeni client wieħed milli jimmonopolizza r-riżorsi;
  • tnaqqas żidiet aċċidentali fit-traffiku;
  • tipproteġi l-kapaċità tad-database, tas-CPU, u tas-servizzi esterni;
  • tinforza limiti differenti għal utenti jew pjanijiet differenti;
  • tirritorna response prevedibbli meta l-kapaċità ma tkunx disponibbli.

Ir-rate limiting mhuwiex protezzjoni sħiħa kontra DDoS. Attakki distribwiti kbar għandhom jiġu ttrattati wkoll fil-konfini tal-infrastruttura, bħal CDN, web application firewall, API gateway, jew servizz ta’ protezzjoni tal-cloud. (learn.microsoft.com)

Il-konfigurazzjoni ta’ policy fixed-window

L-algoritmu fixed-window jippermetti numru definit ta’ requests matul intervall ta’ żmien. Meta jintemm l-intervall, il-counter tiegħu jiġi reset.

Il-konfigurazzjoni Program.cs li ġejja taċċetta 20 request kull minuta u tqiegħed fi queue sa żewġ requests addizzjonali:

using Microsoft.AspNetCore.RateLimiting;
using System.Threading.RateLimiting;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRateLimiter(options =>
{
    options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;

    options.AddFixedWindowLimiter("api", limiterOptions =>
    {
        limiterOptions.PermitLimit = 20;
        limiterOptions.Window = TimeSpan.FromMinutes(1);
        limiterOptions.QueueLimit = 2;
        limiterOptions.QueueProcessingOrder =
            QueueProcessingOrder.OldestFirst;
    });
});

var app = builder.Build();

app.UseRouting();
app.UseRateLimiter();

app.MapGet("/products", () => Results.Ok(new[]
{
    new { Id = 1, Name = "Keyboard" },
    new { Id = 2, Name = "Mouse" }
})).RequireRateLimiting("api");

app.Run();

PermitLimit jiddefinixxi kemm requests jiġu aċċettati, filwaqt li Window jiddefinixxi meta l-permessi jerġgħu jimtlew. QueueLimit jikkontrolla kemm requests jistgħu jistennew permess. Jekk jiġi ssettjat għal żero, ir-requests żejda jiġu rrifjutati immedjatament.

Għal policies speċifiċi għal endpoint, UseRateLimiter għandu jitħaddem wara UseRouting. (learn.microsoft.com)

Ir-ritorn ta’ response 429 utli

B’mod awtomatiku, requests irrifjutati jistgħu jirċievu l-HTTP status code 429 Too Many Requests. Callback OnRejected jippermetti lill-API tirritorna response aktar ċar u, meta jkun disponibbli, header Retry-After.

builder.Services.AddRateLimiter(options =>
{
    options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;

    options.OnRejected = async (context, cancellationToken) =>
    {
        if (context.Lease.TryGetMetadata(
            MetadataName.RetryAfter,
            out var retryAfter))
        {
            context.HttpContext.Response.Headers.RetryAfter =
                ((int)retryAfter.TotalSeconds).ToString();
        }

        await context.HttpContext.Response.WriteAsJsonAsync(new
        {
            error = "Too many requests. Please try again later."
        }, cancellationToken);
    };

    options.AddFixedWindowLimiter("api", limiterOptions =>
    {
        limiterOptions.PermitLimit = 20;
        limiterOptions.Window = TimeSpan.FromMinutes(1);
        limiterOptions.QueueLimit = 0;
    });
});

Il-valur Retry-After jgħin lill-clients jiddeċiedu meta request ieħor x’aktarx jirnexxi. Xorta huwa importanti li l-clients jimmaniġġjaw responses 429 minflok jassumu li kull request se jiġi aċċettat.

Limitazzjoni separata għal kull client

Policy waħda kondiviża tfisser li kull min jagħmel request jikkonsma mill-istess kwota ta’ requests. Il-partitioning joħloq limiter separat għal kull utent, API key, tenant, jew indirizz IP.

options.AddPolicy("per-client", httpContext =>
{
    var clientId =
        httpContext.User.Identity?.Name ??
        httpContext.Connection.RemoteIpAddress?.ToString() ??
        "anonymous";

    return RateLimitPartition.GetFixedWindowLimiter(
        partitionKey: clientId,
        factory: _ => new FixedWindowRateLimiterOptions
        {
            PermitLimit = 10,
            Window = TimeSpan.FromMinutes(1),
            QueueLimit = 0,
            AutoReplenishment = true
        });
});

Applikaha bħal kull named policy oħra:

app.MapPost("/orders", CreateOrder)
   .RequireRateLimiting("per-client");

ID ta’ utent awtentikat jew API key ikkontrollata ġeneralment tkun partition key aktar affidabbli minn indirizz IP. Applikazzjonijiet wara proxies għandhom ukoll jikkonfiguraw il-forwarded headers b’mod korrett qabel jiddependu fuq l-IP tal-client.

L-għażla ta’ algoritmu

Uża fixed window meta kwota sempliċi tkun biżżejjed. Uża sliding window għal limiti aktar gradwali bejn il-konfini tal-intervalli. Uża token bucket meta bursts ikkontrollati jkunu aċċettabbli. Uża concurrency limiting meta t-tħassib ewlieni jkun kemm operazzjonijiet għaljin jitħaddmu fl-istess ħin, aktar milli kemm requests jaslu kull minuta. (learn.microsoft.com)

Qabel production deployment, żomm il-limiti fil-konfigurazzjoni, immonitorja r-requests irrifjutati, u wettaq load test tal-valuri magħżula. Limitu għandu jirrifletti l-ispiża u l-kapaċità reali tal-endpoint protett—mhux numru arbitrarju kkupjat fl-API kollha.

Referenzi