Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rate Limiting

Le Rate Limiting (limitation de débit) est une technique essentielle pour protéger une API contre les abus, les attaques par déni de service (DoS) et pour gérer équitablement les ressources du serveur.

Cela consiste à limiter le nombre de requêtes qu’un client (identifié par son IP ou son ID utilisateur) peut effectuer dans un intervalle de temps donné.

Le concept

Imaginez un tourniquet à l’entrée d’un métro. Si tout le monde essaie de passer en même temps, ça bloque. Le Rate Limiting, c’est comme imposer un délai d’une seconde entre chaque passage.

En ASP.NET Core, depuis la version 7, un middleware de Rate Limiting est intégré nativement.

Configuration

1. Enregistrement du service

Dans Program.cs, on configure les règles (policies) de limitation.

Il existe plusieurs algorithmes. Le plus courant est la Fixed Window (Fenêtre fixe). Par exemple : “Max 10 requêtes par minute”.

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

// ...

builder.Services.AddRateLimiter(options =>
{
    // Rejet avec le code 429 Too Many Requests
    options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;

    // Définition d'une politique nommée "fixed"
    options.AddFixedWindowLimiter("fixed", limiterOptions =>
    {
        limiterOptions.PermitLimit = 10; // Max 10 requêtes
        limiterOptions.Window = TimeSpan.FromSeconds(10); // Toutes les 10 secondes
        limiterOptions.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
        limiterOptions.QueueLimit = 0; // Pas de file d'attente
    });
});

2. Activation du middleware

Comme toujours, il faut l’ajouter au pipeline dans Program.cs.

app.UseRateLimiter();
Placez `UseRateLimiter` après `UseCors` et avant `MapControllers`.

Utilisation

Une fois configuré, vous pouvez appliquer le Rate Limiting sur vos contrôleurs ou vos routes avec l’attribut [EnableRateLimiting].

[ApiController]
[Route("api/[controller]")]
[EnableRateLimiting("fixed")] // Applique la politique "fixed" à tout le contrôleur
public class GameController : ControllerBase
{
    // ...
}

Vous pouvez aussi désactiver le rate limiting sur une action spécifique :

[DisableRateLimiting]
[HttpGet("status")]
public IActionResult GetStatus()
{
    return Ok("Online");
}

Rate Limiting par Utilisateur

L’exemple précédent limite tout le monde globalement ou par IP (selon la configuration par défaut). Pour limiter par utilisateur connecté, il faut utiliser le partitionnement.

options.AddPolicy("user-limit", context =>
{
    // On récupère le nom de l'utilisateur (ou son IP s'il n'est pas connecté)
    var username = context.User.Identity?.Name ?? context.Connection.RemoteIpAddress?.ToString();

    return RateLimitPartition.GetFixedWindowLimiter(username, _ => new FixedWindowRateLimiterOptions
    {
        PermitLimit = 5,
        Window = TimeSpan.FromSeconds(10)
    });
});

Cette configuration crée un compteur séparé pour chaque utilisateur. Alice peut faire 5 requêtes, et Bob peut aussi en faire 5, sans qu’ils se bloquent mutuellement.