How to implement rate limiting in ASP.NET Core

By FoxLearn 1/3/2025 9:13:05 AM   105
Rate limiting in ASP.NET Core helps protect web applications from malicious attacks, such as denial-of-service (DoS) attacks, by controlling the frequency of requests from users.

It limits the number of requests an IP address can make within a short time period.

To implement rate limiting in ASP.NET Core, you'll use a rate limiting middleware package designed for the framework. This middleware allows you to define rate limits for various scenarios, such as restricting the number of requests an IP address (or a range of IPs) can make within a specific time window, which can be set per second, minute, or any other time period.

Once you've created your ASP.NET Core API project in Visual Studio, you need to install the AspNetCoreRateLimit package for rate limiting.

You can add it either through the NuGet Package Manager in Visual Studio or by running the following command in the .NET CLI:

dotnet add package AspNetCoreRateLimit

Configure rate limiting middleware in ASP.NET Core

After installing the AspNetCoreRateLimit package, you need to add the rate limiting middleware to the request-response pipeline by modifying the ConfigureServices method in your project.

using AspNetCoreRateLimit;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// Add rate limiting services
builder.Services.AddOptions();
builder.Services.AddMemoryCache();

// Configure rate limiting options from appsettings.json
builder.Services.Configure<IpRateLimitOptions>(builder.Configuration.GetSection("IpRateLimit"));

// Register rate limiting stores and configuration
builder.Services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
builder.Services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();

// Add HttpContextAccessor
builder.Services.AddHttpContextAccessor();

var app = builder.Build();

// Enable rate limiting middleware
app.UseIpRateLimiting();

// Enable middleware for Swagger and API documentation (optional)
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseAuthorization();

app.MapControllers();

app.Run();

For old ASP.NET Core

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    services.AddOptions();
    services.AddMemoryCache();
    services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimit"));
    services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
    services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
    services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
    services.AddHttpContextAccessor();
}

In this code, notice the use of the IpRateLimit section, which is referenced in the appsettings.json file.

Add Rate Limiting Configuration in appsettings.json

In the appsettings.json file, you define rate limit rules by specifying an endpoint, a time period, and a request limit. These rules control how many requests are allowed to be made to an endpoint within a specified time window.

{
  "IpRateLimit": {
    "IpWhitelist": ["127.0.0.1"], // Optional: Define IPs to bypass rate limiting
    "GeneralRules": [
      {
        "Endpoint": "*", 
        "Period": "1m",  // Time window (e.g., 1 minute)
        "Limit": 100     // Max requests allowed in the period
      }
    ]
  }
}

The rate limit rule ensures that any endpoint with "/api" in the URI is restricted to five requests per minute.

In your project, create a new controller class named ValuesController.

using Microsoft.AspNetCore.Mvc;

namespace YourNamespace.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        // GET: api/values
        [HttpGet]
        public IActionResult Get()
        {
            // Return a simple value for testing
            return Ok(new string[] { "value1", "value2" });
        }
    }
}

This will be the default controller that will be called when you test the rate limiting.

Once the controller is created, make sure your application is running by pressing Ctrl + F5 or using the dotnet run command. Navigate to the endpoint in your browser or using a tool like Postman to test the API.

For example, open the browser and go to:

http://localhost:5000/api/values

You should see a response like this:

["value1", "value2"]

After making sure everything is set up and your app is running, test by sending GET requests to http://localhost:5000/api/values. Once the limit of 5 requests is reached within a minute, you'll receive a response indicating the rate limit has been exceeded.