[c#] Cómo proteger una API web de ASP.NET



Answers

Sugeriría comenzar primero con las soluciones más sencillas: tal vez basta con la autenticación HTTP básica básica + HTTPS en su escenario.

Si no es así (por ejemplo, no puede usar https, o necesita una administración de claves más compleja), puede echarle un vistazo a las soluciones basadas en HMAC según lo sugerido por otros. Un buen ejemplo de dicha API sería Amazon S3 ( http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html )

Escribí una publicación de blog sobre la autenticación basada en HMAC en ASP.NET Web API. Discute tanto el servicio de API web como el cliente de API web y el código está disponible en bitbucket. http://www.piotrwalat.net/hmac-authentication-in-asp-net-web-api/

Aquí hay una publicación sobre Autenticación básica en la API web: http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-message-handlers/

Recuerde que si va a proporcionar una API a terceros, también es probable que sea responsable de la entrega de las bibliotecas de los clientes. La autenticación básica tiene una ventaja significativa aquí, ya que es compatible con la mayoría de las plataformas de programación listas para usar. HMAC, por otro lado, no está tan estandarizado y requerirá una implementación personalizada. Estos deberían ser relativamente sencillos pero aún requieren trabajo.

PD. También hay una opción para usar certificados HTTPS +. http://www.piotrwalat.net/client-certificate-authentication-in-asp-net-web-api-and-windows-store-apps/

Question

Quiero construir un servicio web RESTful utilizando ASP.NET Web API que los desarrolladores de terceros utilizarán para acceder a los datos de mi aplicación.

He leído mucho sobre OAuth y parece ser el estándar, pero encontrar una buena muestra con documentación que explique cómo funciona (¡y que realmente funciona!) Parece ser increíblemente difícil (especialmente para un novato en OAuth).

¿Hay una muestra que realmente construye y funciona y muestra cómo implementar esto?

He descargado numerosas muestras:

  • DotNetOAuth: la documentación es inútil desde la perspectiva de un novato
  • Thinktecture: no se puede construir

También he observado blogs que sugieren un esquema simple basado en token (como this ): esto parece reinventar la rueda, pero tiene la ventaja de ser conceptualmente bastante simple.

Parece que hay muchas preguntas como esta en SO, pero no hay buenas respuestas.

¿Qué están haciendo todos en este espacio?




Web API introdujo un atributo [Authorize] para proporcionar seguridad. Esto puede establecerse globalmente (global.asx)

public static void Register(HttpConfiguration config)
{
    config.Filters.Add(new AuthorizeAttribute());
}

O por controlador:

[Authorize]
public class ValuesController : ApiController{
...

Por supuesto, su tipo de autenticación puede variar y es posible que desee realizar su propia autenticación; cuando esto ocurra, puede encontrar una herencia útil de Atributo Autorizado y ampliarla para cumplir con sus requisitos:

public class DemoAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (Authorize(actionContext))
        {
            return;
        }
        HandleUnauthorizedRequest(actionContext);
    }

    protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        var challengeMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
        challengeMessage.Headers.Add("WWW-Authenticate", "Basic");
        throw new HttpResponseException(challengeMessage);
    }

    private bool Authorize(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        try
        {
            var someCode = (from h in actionContext.Request.Headers where h.Key == "demo" select h.Value.First()).FirstOrDefault();
            return someCode == "myCode";
        }
        catch (Exception)
        {
            return false;
        }
    }
}

Y en tu controlador:

[DemoAuthorize]
public class ValuesController : ApiController{

Aquí hay un enlace sobre otra implementación personalizada para autorizaciones de WebApi:

http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-membership-provider/




en la continuación de la respuesta de @ Cuong Le, mi enfoque para evitar el ataque de repetición sería

// Cifrar el tiempo Unix en el lado del cliente usando la clave privada compartida (o la contraseña del usuario)

// Enviarlo como parte del encabezado de solicitud al servidor (API WEB)

// Descifrar el tiempo de Unix en el servidor (API WEB) utilizando la clave privada compartida (o la contraseña del usuario)

// Verificar la diferencia de tiempo entre el Tiempo Unix del Cliente y el Tiempo Unix del Servidor, no debe ser mayor que x sec

// si User ID / Hash Password es correcta y el UnixTime descifrado está dentro de x seg de la hora del servidor, entonces es una solicitud válida




Related