Securing ASP.NET Core Web APIs: Rate Limiting, JWT Hardening, & Defense in Depth
Hardening ASP.NET Core Web APIs against DDoS and auth flaws using PartitionedRateLimiter, strict JWT validation, and defense-in-depth middleware.
· 11 min read · Advanced
Key takeaways
- Configure .NET 8/9 native PartitionedRateLimiter with sliding-window policies per API key/IP.
- Harden JWT validation with strict ClockSkew, Audience, Issuer, and SecurityKey checks.
- Implement Global Exception Handling middleware without leaking stack traces.
- Apply Content-Security-Policy (CSP), Strict-Transport-Security (HSTS), and CORS lockdown.
Getting an API to handle load is the easy half. The part that separates a prototype from something you'd actually run in production is whether it survives automated abuse, injection attempts, and authorization bypasses — none of which show up in a happy-path demo.
1. Native .NET Rate Limiting Middleware
You no longer need a third-party package for this. Since .NET 7/8, Microsoft.AspNetCore.RateLimiting ships built in, and it covers the common cases — sliding window, token bucket — out of the box.
// Program.cs: Sliding Window Rate Limiting per IP Address
builder.Services.AddRateLimiter(options =>
{
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
options.AddPolicy("FixedPerIp", httpContext =>
{
var clientIp = httpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown";
return RateLimitPartition.GetSlidingWindowLimiter(clientIp, _ => new SlidingWindowRateLimiterOptions
{
PermitLimit = 60,
Window = TimeSpan.FromMinutes(1),
SegmentsPerWindow = 6,
QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
QueueLimit = 0
});
});
});
2. Bulletproof JWT Token Validation
Set ClockSkew explicitly. The default is a 5-minute leeway, which sounds harmless until you realize it means an expired token can still validate for five minutes past expiry — not something you want in a high-security context.
Security is not an afterthought or an add-on module. It is an architectural foundation woven into every endpoint and data layer.