在ASP.NET MVC中实现请求限制的最佳方式是什么?

我们正在尝试各种方法来限制用户在给定时间内的操作

  • 限制问题/回答post
  • 限制编辑
  • 限制供稿检索

目前,我们正在使用caching来插入用户活动的logging – 如果该logging存​​在/当用户执行相同的活动时,我们就进行调​​节。

使用caching会自动给我们提供过时的数据清理和滑动用户的活动窗口,但如何扩展可能是一个问题。

什么是确保请求/用户操作可以被有效抑制的其他方法(强调稳定性)?

下面是我们在去年使用Stack Overflow的一个通用版本:

/// <summary> /// Decorates any MVC route that needs to have client requests limited by time. /// </summary> /// <remarks> /// Uses the current System.Web.Caching.Cache to store each client request to the decorated route. /// </remarks> [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class ThrottleAttribute : ActionFilterAttribute { /// <summary> /// A unique name for this Throttle. /// </summary> /// <remarks> /// We'll be inserting a Cache record based on this name and client IP, eg "Name-192.168.0.1" /// </remarks> public string Name { get; set; } /// <summary> /// The number of seconds clients must wait before executing this decorated route again. /// </summary> public int Seconds { get; set; } /// <summary> /// A text message that will be sent to the client upon throttling. You can include the token {n} to /// show this.Seconds in the message, eg "Wait {n} seconds before trying again". /// </summary> public string Message { get; set; } public override void OnActionExecuting(ActionExecutingContext c) { var key = string.Concat(Name, "-", c.HttpContext.Request.UserHostAddress); var allowExecute = false; if (HttpRuntime.Cache[key] == null) { HttpRuntime.Cache.Add(key, true, // is this the smallest data we can have? null, // no dependencies DateTime.Now.AddSeconds(Seconds), // absolute expiration Cache.NoSlidingExpiration, CacheItemPriority.Low, null); // no callback allowExecute = true; } if (!allowExecute) { if (String.IsNullOrEmpty(Message)) Message = "You may only perform this action every {n} seconds."; c.Result = new ContentResult { Content = Message.Replace("{n}", Seconds.ToString()) }; // see 409 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html c.HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict; } } } 

示例用法:

 [Throttle(Name="TestThrottle", Message = "You must wait {n} seconds before accessing this url again.", Seconds = 5)] public ActionResult TestThrottle() { return Content("TestThrottle executed"); } 

ASP.NET Cache在这里就像一个冠军 – 通过使用它,你可以自动清理你的油门条目。 而随着我们日益增长的stream量,我们没有看到这是服务器上的问题。

随意就此方法提供反馈意见; 当我们使堆栈溢出更好,你得到你的Ewok修复更快:)

微软有一个新的IIS 7扩展,称为IIS 7.0的dynamicIP限制扩展 – testing版。

“IIS 7.0的dynamicIP限制是一个模块,可以防止拒绝服务和网页服务器和网站上的powershell攻击,这种保护是通过暂时阻止那些发出exception高数量并发请求的HTTP客户端的IP地址或者在很短的时间内发出大量请求。“ http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/

例:

如果您将标准设置为在X requests in Y milliseconds后发出X requests in Y milliseconds或者X requests in Y milliseconds X concurrent connections in Y milliseconds则IP地址将X concurrent connections in Y milliseconds内被屏蔽,然后再次允许请求。

我们使用从这个URL http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx借来的技术,不是为了节制,而是为了穷人的拒绝服务(DOS)。; 这也是基于caching的,可能与您所做的相似。 你是否阻止DOS攻击? 路由器当然可以用来减lessDOS; 你认为路由器可以处理你需要的节stream吗?