ASP.NET Core RateLimit doesn't work in .NET 6

906 Views Asked by At

This is my call POST:

[ApiController]
[Route("api/[controller]")]
public class SuperAdminController : ControllerBase
{
    private IUserRepository _userRepository;

    public SuperAdminController(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    [Route("Add")]
    [HttpPost]
    public async Task<IActionResult> Add([FromBody] AddSuperAdmin addSuperAdmin)
    {
        if (addSuperAdmin.SecretKey == Environment.GetEnvironmentVariable("SecretKey"))
        {
            if (ModelState.IsValid)
            {
                var identityUser = new IdentityUser
                    {
                        UserName = addSuperAdmin.Email,
                        Email = addSuperAdmin.Email
                    };

                var roles = new List<string>
                {
                    "User",
                    "Admin",
                    "SuperAdmin"
                };

                var result = await _userRepository.Add(identityUser, addSuperAdmin.Password, roles);

                if (result.Count() == 0)
                {
                    return Ok("Le super admin a bien été ajouté!");
                }
                else
                {
                    return BadRequest(Utils.FormatMesageAddUser(result));
                }
            }
            else
            {
                return BadRequest(Utils.FormatMessageAdmin(ModelState));
            }
        }

        return BadRequest("Mauvaise clé secrète.");
    }
}

This is my program:

// AspNetCoreRateLimit
builder.Services.AddMemoryCache();
builder.Services.Configure<IpRateLimitOptions>(builder.Configuration.GetSection("IpRateLimiting"));
builder.Services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
builder.Services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
builder.Services.AddSingleton<IProcessingStrategy, AsyncKeyLockProcessingStrategy>();
builder.Services.AddInMemoryRateLimiting();

This is my appsettings.json:

{
  "DetailedErrors": true,
  "IpRateLimiting": {
    "EnableEndpointRateLimiting": true,
    "StackBlockedRequests": false,
    "RealIPHeader": "X-Real-IP",
    "ClientIdHeader": "X-ClientId",
    "HttpStatusCode": 429,
    "GeneralRules": [
      {
        "Endpoint": "*:/SuperAdmin/*",
        "Period": "5s",
        "Limit": 2
      }
    ]
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

When I call it with Postman more than 2 times in 5 seconds, I don't get a 429 error.

What have I missed?

I followed this article. I implemented the nuget method, but it doesn't work.

1

There are 1 best solutions below

3
Guru Stron On

Check out the package docs. Article (and the provided code) does not mention adding the rate limiting middleware to the pipeline:

var app = builder.Build();

// ...

// somewhere near the start of the pipeline
app.UseIpRateLimiting();

Do not forget to add api prefix to the endpoint definition since you have it in the route template:

[Route("api/[controller]")]
{
  // ...
  "IpRateLimiting": {
    // ...
    "GeneralRules": [
      {
        "Endpoint": "*:/api/SuperAdmin/*",
        "Period": "5s",
        "Limit": 2
      }
    ]
  },
  // ...
}