AppRateLimiter.Web
1.0.0
dotnet add package AppRateLimiter.Web --version 1.0.0
NuGet\Install-Package AppRateLimiter.Web -Version 1.0.0
<PackageReference Include="AppRateLimiter.Web" Version="1.0.0" />
<PackageVersion Include="AppRateLimiter.Web" Version="1.0.0" />
<PackageReference Include="AppRateLimiter.Web" />
paket add AppRateLimiter.Web --version 1.0.0
#r "nuget: AppRateLimiter.Web, 1.0.0"
#:package AppRateLimiter.Web@1.0.0
#addin nuget:?package=AppRateLimiter.Web&version=1.0.0
#tool nuget:?package=AppRateLimiter.Web&version=1.0.0
AppRateLimiter.Web
Classic ASP.NET (System.Web) integration for AppRateLimiter.
The core middleware targets ASP.NET Core, so it covers modern .NET and ASP.NET Core 2.x on .NET Framework. This package adds an async IHttpModule for the classic System.Web pipeline, which is what WebForms, MVC 5, and Web API 2 use. That is the common legacy Windows scenario: an IIS web farm behind a load balancer. Point the module at the Redis store and every server in the farm shares one global counter.
Install
dotnet add package AppRateLimiter.Web
Targets net472. It brings in the core AppRateLimiter, and AppRateLimiter.Redis for the distributed store.
Configure (Global.asax)
Classic modules cannot use dependency injection, so you supply the store and rules once at startup through a static entry point.
using System;
using AppRateLimiter;
using AppRateLimiter.Redis;
using AppRateLimiter.Web;
public class Global : System.Web.HttpApplication
{
protected void Application_Start()
{
// Single server: in-memory store.
IRateLimitStore store = new InMemoryRateLimitStore();
// IIS web farm behind a load balancer: shared Redis store instead, so the limit is
// global across all servers.
// IRateLimitStore store = new RedisRateLimitStore(
// StackExchange.Redis.ConnectionMultiplexer.Connect("my-redis:6379"), "rl:");
RateLimitHttpModule.Configure(
store,
ipRules: new[]
{
WebRateLimitRules.ByIp(permitLimit: 100, window: TimeSpan.FromMinutes(1)),
},
claimRules: new[]
{
WebRateLimitRules.ByClaim("sub", permitLimit: 1000, window: TimeSpan.FromMinutes(1)),
});
}
}
Register the module (web.config)
<configuration>
<system.webServer>
<modules>
<add name="AppRateLimiter"
type="AppRateLimiter.Web.RateLimitHttpModule, AppRateLimiter.Web" />
</modules>
</system.webServer>
</configuration>
That is all. IP rules run before authentication on BeginRequest, and claim rules run after authentication on PostAuthenticateRequest, reading the validated HttpContext.User.
When a limit is exceeded
The request short-circuits with the same contract as the ASP.NET Core middleware:
429 Too Many RequestsRetry-After: <seconds>header- body
{"error":"rate_limit_exceeded","retryAfterSeconds":<n>}
What it preserves
This adapter keeps the same security properties as the core:
- Atomic counting, no over-admission. It calls the same
IRateLimitStore(in-memory or the atomic Redis Lua script), and awaitsHitAsyncthroughEventHandlerTaskAsyncHelperrather than blocking a thread. - Claims from the validated identity only.
ByClaimreads fromHttpContext.Userafter authentication and skips unauthenticated requests, so a client cannot point a counter at another principal's bucket. - No X-Forwarded-For spoofing. The client IP comes from the connection.
X-Forwarded-Foris honored only when the direct peer is one of the trusted proxies you pass in, walking the chain right to left and skipping trusted hops. - IPv6 rotation contained. IPv6 clients are keyed by their /64 prefix, and IPv4-mapped addresses fold to plain IPv4, exactly like the core.
- Same key namespacing. Rules use the same name based key separator as the core, so when the module and the ASP.NET Core middleware share one store they also share buckets.
Authentication note
Populate HttpContext.User with a ClaimsPrincipal before PostAuthenticateRequest completes (for example via your existing forms/JWT/OWIN authentication). ByClaim reads claims with ClaimsPrincipal.FindFirst(type).
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET Framework | net472 is compatible. net48 was computed. net481 was computed. |
-
.NETFramework 4.7.2
- AppRateLimiter (>= 1.0.0)
- AppRateLimiter.Redis (>= 1.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 47 | 6/2/2026 |