How do I implement rate limiting in an ASP.NET MVC site?
.Net 6
Check it out:
Nuget: https://www.nuget.org/packages/DotNetRateLimiter/
It is simple:
[HttpGet("")]
[RateLimit(PeriodInSec = 60, Limit = 3)]
public IEnumerable<WeatherForecast> Get()
{
....
}
And even you can control request by route or query parameters:
[HttpGet("by-query/{id}")]
[RateLimit(PeriodInSec = 60, Limit = 3, RouteParams = "id", QueryParams = "name,family")]
public IEnumerable<WeatherForecast> Get(int id, string name, [FromQuery] List<string> family)
{
....
}
If you are using IIS 7 you could take a look at the Dynamic IP Restrictions Extension. Another possibility is to implement this as an action filter:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class RateLimitAttribute : ActionFilterAttribute
{
public int Seconds { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Using the IP Address here as part of the key but you could modify
// and use the username if you are going to limit only authenticated users
// filterContext.HttpContext.User.Identity.Name
var key = string.Format("{0}-{1}-{2}",
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
filterContext.ActionDescriptor.ActionName,
filterContext.HttpContext.Request.UserHostAddress
);
var allowExecute = false;
if (HttpRuntime.Cache[key] == null)
{
HttpRuntime.Cache.Add(key,
true,
null,
DateTime.Now.AddSeconds(Seconds),
Cache.NoSlidingExpiration,
CacheItemPriority.Low,
null);
allowExecute = true;
}
if (!allowExecute)
{
filterContext.Result = new ContentResult
{
Content = string.Format("You can call this every {0} seconds", Seconds)
};
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
}
}
}
And then decorate the action that needs to be limited:
[RateLimit(Seconds = 10)]
public ActionResult Index()
{
return View();
}
Have a look at Jarrod's answer on how they do this on SO.
StackOverflow MVC Throttling
Some example code as well as explanation on how it works.