Limitando taxa de requisições
ResumoRate limiting protege a API de abuso e sobrecarga limitando quantas requisições um cliente pode fazer por janela de tempo. O .NET traz o middleware nativo
RateLimitercom várias políticas.
1. Objetivos de Aprendizagem#
- Explicar por que aplicar rate limiting.
- Configurar o middleware nativo com uma política (ex.: fixed window).
- Personalizar a resposta
429 Too Many Requests.
2. Pré-requisitos#
- Pipeline e middleware (Módulo 16).
3. Conceito#
Rate limiting controla o fluxo de requisições, protegendo contra abuso, brute force e picos. O porquê: preservar disponibilidade e custo. O .NET oferece algoritmos prontos:
- Fixed window — N requisições por janela fixa.
- Sliding window — janela deslizante, mais suave.
- Token bucket — permite rajadas controladas.
- Concurrency — limita requisições simultâneas.
4. Mão na Massa#
4.1. Setup#
O RateLimiter é nativo (namespace Microsoft.AspNetCore.RateLimiting), sem pacote externo.
4.2. Implementação Passo a Passo#
- Configuração:
using System.Threading.RateLimiting;
builder.Services.AddRateLimiter(options =>
{
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
options.AddFixedWindowLimiter("fixed", limiter =>
{
limiter.PermitLimit = 10;
limiter.Window = TimeSpan.FromSeconds(10);
limiter.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
limiter.QueueLimit = 0;
});
});
- Pipeline (antes do roteamento das ações):
app.UseRateLimiter();
- Aplicar a política a um controller/ação:
[EnableRateLimiting("fixed")]
[HttpGet]
public IActionResult Get() => Ok();
- Resposta customizada ao rejeitar:
options.OnRejected = async (context, ct) =>
{
context.HttpContext.Response.Headers.RetryAfter = "10";
await context.HttpContext.Response.WriteAsync(
"Limite de requisições excedido. Tente novamente em instantes.", ct);
};
4.3. Executando#
for i in $(seq 1 12); do curl -s -o /dev/null -w "%{http_code}\n" http://localhost:5000/api/produtos; done
# as primeiras respondem 200; ao exceder, 429
5. Exemplo Completo#
Combine uma política global padrão com políticas específicas por endpoint sensível (ex.: login mais restrito que leitura pública).
6. Boas Práticas e Armadilhas#
| Faça | Evite |
|---|---|
Incluir Retry-After na resposta 429 | Rejeitar sem orientar o cliente |
| Particionar o limite por cliente/API key/IP | Um limite global que penaliza todos juntos |
| Limites mais rígidos em endpoints de autenticação | Mesmo limite para login e leitura pública |
Atençãoatrás de proxy/load balancer, o IP visto pela aplicação pode ser o do proxy. Configure
ForwardedHeaderspara particionar por IP real, senão todos caem no mesmo balde.
7. Segurança e Produção#
- Rate limiting é defesa de primeira linha contra brute force e credential stuffing em endpoints de login.
- Em cenários distribuídos (múltiplas instâncias), um limitador em memória não é compartilhado — considere um store distribuído (ex.: Redis).
8. Exercícios#
- Fácil: ajuste o limite para 5 requisições por 5 segundos.
- Médio: aplique uma política mais restrita ao endpoint de login.
- Desafio: particione o limitador por API key usando
PartitionedRateLimiter.
9. Resumo#
O middleware nativo de rate limiting oferece políticas (fixed/sliding window, token bucket, concurrency), respondendo 429 com Retry-After. Particione por cliente e reforce endpoints sensíveis.
10. Próximos Passos#
Módulo 40: autenticação e autorização com JWT e Identity.
11. Referências#
- Microsoft Learn — Rate limiting no ASP.NET Core
- Microsoft Learn — System.Threading.RateLimiting
- MDN — 429 Too Many Requests