Filtro de autorización WebApi con token en json payload

He estado investigando la Autorización con AspNetWebApi y la información es un poco escasa sobre el tema.

Tengo las siguientes opciones:

  1. Pase el token de la API en la cadena de consulta
  2. Pasar token API como encabezado
  3. Pase el token de la API mediante la autenticación básica
  4. Pase el token de la API a la carga útil de la solicitud en json.

¿Cuál es generalmente el método recomendado?

También me pregunto por el punto 4), ¿cómo haría para inspeccionar la carga útil json en el método OnAuthorization en AuthorizationFilterAttribute para verificar si el token API es correcto?

preguntado el 03 de mayo de 12 a las 16:05

¿Qué quiere decir con token API? ¿Quieres decir cookie de autenticación? -

Solo un GUID que se puede pasar en cada solicitud para autenticar al cliente. -

1 Respuestas

Si desea una opción verdaderamente segura para la autorización, algo como OAuth es el camino a seguir. Esta blog proporciona una muestra bastante completa utilizando la API web de WCF ahora obsoleta, pero gran parte del código es recuperable. O al menos, use la autenticación básica HTTP como se muestra en este blog. Como señala Aliostad, asegúrese de estar usando HTTPS si sigue la ruta de autenticación básica para que el token permanezca seguro.

Si decide que desea implementar el suyo propio (que casi siempre será mucho menos seguro que cualquiera de las opciones anteriores), a continuación se muestra un ejemplo de código de lo que necesitará para AuthorizationHanlder si utiliza la ruta de encabezado HTTP. Tenga en cuenta que existe una gran posibilidad de que la forma en que se maneja UserPrinicipal en las clases de API web cambie, por lo que este código solo es bueno para la primera versión preliminar. Debería conectar el AuthorizationHandler de esta manera:

    GlobalConfiguration.Configuration.MessageHandlers.Add(new AuthenticationHandler());

Código para token de encabezado:

public class AuthenticationHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        var requestAuthTokenList = GetRequestAuthTokens(request);
        if (ValidAuthorization(requestAuthTokenList))
        {
            //TODO: implement a Prinicipal generator that works for you
            var principalHelper = GlobalConfiguration.Configuration
                .ServiceResolver
                    .GetService(typeof(IPrincipalHelper)) as IPrincipalHelper;

            request.Properties[HttpPropertyKeys.UserPrincipalKey] = 
                principalHelper.GetPrinicipal(request);

            return base.SendAsync(request, cancellationToken);
        }
        /*
        ** This will make the whole API protected by the API token.
        ** To only protect parts of the API then mark controllers/methods
        ** with the Authorize attribute and always return this:
        **
        ** return base.SendAsync(request, cancellationToken);
        */
        return Task<HttpResponseMessage>.Factory.StartNew(
            () => new HttpResponseMessage(HttpStatusCode.Unauthorized)
                {
                    Content = new StringContent("Authorization failed")
                });
    }

    private static bool ValidAuthorization(IEnumerable<string> requestAuthTokens)
    {
        //TODO: get your API from config or however makes sense for you
        var apiAuthorizationToken = "good token";
        var authorized = requestAuthTokens.Contains(apiAuthorizationToken);

        return authorized;
    }

    private static IEnumerable<string> GetRequestAuthTokens(HttpRequestMessage request)
    {
        IEnumerable<string> requestAuthTokens;
        if (!request.Headers.TryGetValues("SomeHeaderApiKey", out requestAuthTokens))
        {
            //Initialize list to contain a single not found token:
            requestAuthTokens = new[] {"No API token found"};
        }
        return requestAuthTokens;
    }
}

contestado el 04 de mayo de 12 a las 13:05

¡Toda la razón, Aliostad! Está tan arraigado que olvidé mencionarlo. ¡¡Gracias!! - Sixto Sáez

¿Hay alguna desventaja entre pasar el token en el encabezado o usar la autenticación básica? ¿Es un no-no poner token API en json con solicitud? Además, ¿cómo funciona el generador principal? - Jaffa

Diría que la separación de preocupaciones sería la razón por la que no pondría el token de autorización en el cuerpo json. Si lo coloca en el cuerpo, existe la posibilidad de que sea parte de lo que se serializa en sus modelos. Si eso es lo que quieres, hazlo. - Sixto Sáez

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.