Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

.NET 7 Rate Limiting – Rate limit by Client

I have to implement rate limiting to public endpoints using .Net 7 new Rate limiting Middleware.
For now I’ve settled on a fixedWindow rate limiter.
I’ve found many differents implementations online, but the only ones I found implementing any kind of filtering on IP/Client are using the globalLimiter which I dont want.
I have many endpoints and I want 2 different limiters on 2 of my public endpoints.
What I want is a mix of the 2 following implementation, which allows me to name the policy to implement it on only the endpoints, and the rate limiting to be per/client.

2 different policies I can assign to each of my endpoints:

builder.Services.AddRateLimiter(options =>
{
    options.AddFixedWindowLimiter("myRateLimiter1", options =>
    {
        options.AutoReplenishment = true;
        options.PermitLimit = 1;
        options.Window = TimeSpan.FromSeconds(30);
    });
    options.AddFixedWindowLimiter("myRateLimiter12", options =>
    {
        options.AutoReplenishment = true;
        options.PermitLimit = 1;
        options.Window = TimeSpan.FromSeconds(30);
    });
});

Filtering clients that is implemented globally

builder.Services.AddRateLimiter(options =>
{
    options.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>
        RateLimitPartition.GetFixedWindowLimiter(
            partitionKey: httpContext.User.Identity?.Name ?? httpContext.Request.Headers.Host.ToString(),
            factory: partition => new FixedWindowRateLimiterOptions
            {
                AutoReplenishment = true,
                PermitLimit = 1,
                QueueLimit = 0,
                Window = TimeSpan.FromSeconds(30)
            }));
});

I also found this implementation that does the job but cant find how to add filtering either

app.UseRateLimiter(new RateLimiterOptions
{
    OnRejected = (context, _) =>
    {
        if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter))
        {
            context.HttpContext.Response.Headers.RetryAfter =
                ((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo);

            app.Logger.LogWarning("Rate limit exceeded, retry after {RetryAfter} seconds", retryAfter.TotalSeconds);
        }

        context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;

        return new ValueTask();
    }
}
.AddFixedWindowLimiter("myRateLimiter1", options =>
{
    options.AutoReplenishment = true;
    options.PermitLimit = 1;
    options.Window = TimeSpan.FromSeconds(10);
    options.QueueLimit = 0;
}).AddFixedWindowLimiter("myRateLimiter2", options =>
{
    options.AutoReplenishment = true;
    options.PermitLimit = 1;
    options.Window = TimeSpan.FromSeconds(10);
    options.QueueLimit = 0;
}));

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Add your limiters via RateLimiterOptions.AddPolicy:

builder.Services.AddRateLimiter(options =>
{
    options.AddPolicy("myRateLimiter1", context => RateLimitPartition.GetFixedWindowLimiter(
        partitionKey: context.User.Identity?.Name ?? context.Request.Headers.Host.ToString(),
        factory: partition => new FixedWindowRateLimiterOptions
        {
            AutoReplenishment = true,
            PermitLimit = 1,
            QueueLimit = 0,
            Window = TimeSpan.FromSeconds(30)
        }));
    // and the second one
});
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading