如何在ASP.NET MVC站点中实现速率限制?

问题描述 投票:12回答:2

我正在构建一个ASP.NET MVC站点,我想限制经过身份验证的用户使用该站点的某些功能的频率。

虽然我从根本上理解了速率限制是如何工作的,但我无法想象如何以编程方式实现它而不会产生主要的代码气味。

你能用C#示例代码指出一个简单而强大的解决方案来解决这个问题吗?

如果重要,所有这些功能目前都表示为仅接受HTTP POST的动作。我最终可能希望对HTTP GET函数实现速率限制,所以我正在寻找适用于所有这些情况的解决方案。

c# asp.net asp.net-mvc limit rate-limiting
2个回答
18
投票

如果您使用的是IIS 7,可以查看Dynamic IP Restrictions Extension。另一种可能性是将其实现为动作过滤器:

[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;
        }
    }
}

然后装饰需要限制的动作:

[RateLimit(Seconds = 10)]
public ActionResult Index()
{
    return View();
}

4
投票

看看Jarrod关于他们如何在SO上做到这一点的答案。

StackOverflow MVC Throttling

一些示例代码以及它如何工作的解释。

© www.soinside.com 2019 - 2024. All rights reserved.