質問

私たちは、ユーザーのアクションを制限するさまざまな方法を実験しています。 与えられた期間:

  • 質問/回答の投稿を制限する
  • 編集を制限する
  • フィードの取得を制限する

当面は、キャッシュを使用してユーザー アクティビティのレコードを単純に挿入します。ユーザーが同じアクティビティを実行したときにそのレコードが存在する場合は、スロットリングします。

キャッシュを使用すると、古いデータが自動的に消去され、ユーザーのアクティビティ ウィンドウがスライドしますが、それをどのように拡張するかが問題になる可能性があります。

(安定性を重視して) リクエストやユーザーのアクションを効果的に抑制できることを保証する他の方法は何ですか?

役に立ちましたか?

解決

これは、過去 1 年間 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, e.g. "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, e.g. "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 キャッシュが優れた機能を発揮します。これを使用すると、スロットル エントリが自動的にクリーンアップされます。また、トラフィックが増加しているため、これがサーバー上の問題であるとはわかりません。

この方法に関するフィードバックをお気軽にお寄せください。Stack Overflow を改善すると、 イウォークの修正 さらに速く:)

他のヒント

Microsoft は、Dynamic IP Restrictions Extension for IIS 7.0 - Beta と呼ばれる IIS 7 用の新しい拡張機能を提供しています。

「IIS 7.0 の動的 IP 制限は、Web サーバーおよび Web サイトに対するサービス拒否攻撃やブルート フォース攻撃に対する保護を提供するモジュールです。このような保護は、異常に多くの同時リクエストを行う、または短期間に大量のリクエストを行う HTTP クライアントの IP アドレスを一時的にブロックすることによって提供されます。 http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/

例:

ブロックする基準を設定した場合 X requests in Y milliseconds または X concurrent connections in Y milliseconds IP アドレスはブロックされます Y milliseconds その後、リクエストは再び許可されます。

この URL から借用したテクニックを使用します http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx, 、スロットルのためではなく、貧しい人のサービス拒否(D.O.S)のためです。これもキャッシュベースであり、あなたがやっていることと似ているかもしれません。D.O.S. を防ぐためにスロットリングを行っていますか?攻撃?ルーターを使用すると D.O.S を削減できます。ルーターが必要なスロットリングを処理できると思いますか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top