Il modo migliore per implementare la limitazione delle richieste in ASP.NET MVC?

StackOverflow https://stackoverflow.com/questions/33969

  •  09-06-2019
  •  | 
  •  

Domanda

Stiamo sperimentando vari modi per limitare le azioni degli utenti in a dato periodo di tempo:

  • Limita i post di domande/risposte
  • Limita le modifiche
  • Limita i recuperi di feed

Per il momento, utilizziamo la cache per inserire semplicemente un record dell'attività dell'utente: se quel record esiste se/quando l'utente esegue la stessa attività, strozziamo.

L'utilizzo della cache ci fornisce automaticamente la pulizia dei dati obsoleti e finestre di attività scorrevoli degli utenti, ma il modo in cui verrà ridimensionato potrebbe essere un problema.

Quali sono altri modi per garantire che le richieste/azioni dell'utente possano essere effettivamente limitate (enfasi sulla stabilità)?

È stato utile?

Soluzione

Ecco una versione generica di ciò che abbiamo utilizzato su Stack Overflow nell'ultimo anno:

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

Utilizzo del campione:

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

La cache ASP.NET funziona come un campione qui: utilizzandola, ottieni la pulizia automatica delle voci dell'acceleratore.E con il nostro traffico in crescita, non vediamo che questo sia un problema sul server.

Sentiti libero di fornire feedback su questo metodo;quando miglioriamo Stack Overflow, ottieni il tuo Correzione Ewok ancora più veloce :)

Altri suggerimenti

Microsoft ha una nuova estensione per IIS 7 denominata Dynamic IP Restrictions Extension for IIS 7.0 - Beta.

"Le restrizioni IP dinamiche per IIS 7.0 sono un modulo che fornisce protezione contro attacchi di tipo Denial of Service e forza bruta su server Web e siti Web.Tale protezione viene fornita bloccando temporaneamente gli indirizzi IP dei client HTTP che effettuano un numero insolitamente elevato di richieste simultanee o che effettuano un gran numero di richieste in un breve periodo di tempo." http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/

Esempio:

Se imposti i criteri per bloccare dopo X requests in Y milliseconds O X concurrent connections in Y milliseconds l'indirizzo IP verrà bloccato per Y milliseconds successivamente le richieste saranno nuovamente consentite.

Usiamo la tecnica presa in prestito da questo URL http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx, non per strozzatura, ma per un povero Denial Of Service (D.O.S).Anche questo è basato sulla cache e potrebbe essere simile a quello che stai facendo.Stai rallentando per impedire che D.O.S.attacchi?I router possono certamente essere utilizzati per ridurre il D.O.S;pensi che un router possa gestire la limitazione di cui hai bisogno?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top