简体   繁体   中英

How do I implement rate limiting in an ASP.NET MVC site?

I'm building an ASP.NET MVC site where I want to limit how often authenticated users can use some functions of the site.

Although I understand how rate-limiting works fundamentally, I can't visualize how to implement it programatically without creating a major code smell.

Can you point me towards a simple yet powerful solution for approaching such a problem, with C# sample code ?

If it matters, all of these functions are currently expressed as Actions that only accept HTTP POST . I may eventually want to implement rate-limiting for HTTP GET functions as well, so I'm looking for a solution that works for all such circumstances.

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.

.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)
{
    ....
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM