Hola a todos, en este post quiero mostrar cómo es posible controlar la cantidad de request permitidos a un endpoint de Web API, para prevenir alteración de datos y/o degradamiento en el performance del servicio.


Pero primero veamos el problema, partiendo de un controllador muy sencillo cómo el siguiente (ten presente que en un escenario real se retornar datos de base de datos, o se hacen inserciones):


public class TestController : ApiController
{
    public string GetString()
    {
        return "Response from TestController";
    }
}

El llamado se realiza por medio de la URL: http://domain/api/test en mi caso tengo http://localhost:28235/api/test, y al hacer la prueba desde Fiddler:

alt

Efectivamente se obtienen los datos sin problema, ahora, usando algún sistema para realizar peticiones HTTP repetidas como Fiddler fácilmente es posible hacer ese llamado n-veces, y ese es el problema y riesgo de seguridad... para simular el caso con Fiddler, damos clic derecho sobre el llamado, luego Replay -> Reissue Sequentially y luego especificamos cuántas veces deseamos repetir el llamado:

alt


Lo anterior puede llegar a convertirse en un verdadero problema, así que una posible solución es controlar la cantidad de request permitidos desde cada IP, para ello vamos a usar WebApiThrottle, así que lo primero es instalarlo por Nuget:

alt

Luego de instalar el paquete, se configura la política de request reiterativos en la clase WebApiConfig, método Register, para el ejemplo he dejado que se permitan solo 10 peticiones por minuto:


public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API ThrottlingHandler Configuration 
        config.MessageHandlers.Add(new ThrottlingHandler()
        {
            Policy = new ThrottlePolicy(perMinute: 10)
            {
                IpThrottling = true
            },
            Repository = new CacheRepository()
        });

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

Al volver a validar, se puede observar que solo los primeros 10 request son aceptados, los demás retornar el código HTTP 429 Too Many Request:

alt

Espero el post les sea de utilidad, y en la página oficial del paquete de Nuget pueden ver todas las opciones de configuraciones de WebApiThrottle

Saludos!