A melhor maneira de implementar o pedido de limitação no ASP.NET MVC?
-
09-06-2019 - |
Pergunta
Estamos experimentando com várias maneiras para limitar as ações do usuário em um determinado período de tempo:
- Limite de pergunta/resposta posts
- Limite de edições
- Limite de alimentação recuperações
Por enquanto, estamos usando o Cache de simplesmente inserir um registro da atividade do usuário - se que existe registro se/quando o usuário faz a mesma atividade, nós do acelerador.
Usando o Cache automaticamente nos dá obsoletos e limpeza de dados de correr atividade windows de usuários, mas como irá escalar pode ser um problema.
Quais são algumas outras maneiras de assegurar que as solicitações/ações do usuário podem ser eficazmente regulado (ênfase na estabilidade)?
Solução
Aqui está uma versão genérica do que temos vindo a utilizar no Estouro de Pilha para o ano passado:
/// <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;
}
}
}
Exemplo de uso:
[Throttle(Name="TestThrottle", Message = "You must wait {n} seconds before accessing this url again.", Seconds = 5)]
public ActionResult TestThrottle()
{
return Content("TestThrottle executed");
}
O ASP.NET Cache funciona como um campeão aqui - usando-o, você recebe limpeza automática do seu acelerador entradas.E com a nossa crescente tráfego, nós não estamos vendo que este é um problema no servidor.
Sinta-se livre para dar o seu feedback sobre este método;quando fazemos um Estouro de Pilha melhor, você tem o seu Ewok correcção ainda mais rápido :)
Outras dicas
A Microsoft tem uma nova extensão para o IIS 7 chamado IP Dinâmico Restrições de Extensão para o IIS 7.0 Beta.
"A Dinâmica Restrições de IP para o IIS 7.0 é um módulo que fornece proteção contra ataques de negação de serviço e ataques de força bruta no servidor web e web sites.Tal proteção é fornecida pela temporariamente o bloqueio de endereços IP do HTTP de clientes, que se tornam anormalmente elevado número de solicitações simultâneas ou que fazem grande número de pedidos sobre o pequeno período de tempo." http://learn.iis.net/page.aspx/548/using-dynamic-ip-restrictions/
Exemplo:
Se você definir os critérios para o bloco X requests in Y milliseconds
ou X concurrent connections in Y milliseconds
o endereço IP será bloqueado para Y milliseconds
solicita, então, será permitido novamente.
Usamos a técnica emprestado a partir deste URL http://www.codeproject.com/KB/aspnet/10ASPNetPerformance.aspx, não para de limitação, mas para um homem pobre de Negação De Serviço (D. O. S).Esta é também a cache de base, e podem ser semelhantes ao que você está fazendo.Você está a limitação para impedir que D. O. S.ataques?Os roteadores podem, certamente, ser utilizado para reduzir D. O. S;você acha que um roteador é capaz de lidar com a limitação de que você precisa?