tutorial route net name frombody asp .net asp.net-mvc-4 authorization asp.net-web-api

.net - route - web api rest c#



Accediendo a la publicación o obteniendo parámetros en la autorización personalizada MVC4 Web Api (5)

Accedí a los datos de la ruta de contexto para obtener los parámetros desde un AuthorizeAttribute personalizado cuando llamé a algo como /api/client/123/users :

public class CustomAuthorizeAttribute : AuthorizeAttribute { protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext) { var clientId = Convert.ToInt32(actionContext.ControllerContext.RouteData.Values["clientid"]); // Check if user can access the client account. } }

¿Es posible acceder a la publicación o obtener parámetros a través del objeto HttpActionContext?

Tengo un conjunto de sensores que registra datos en un servidor web que proporciona una API REST. Me gustaría introducir algún tipo de autenticación / autorización al permitir que los sensores incluyan su identificación de hardware en los datos y luego hacer una búsqueda en una base de datos para ver si la identificación existe o no. Dado que la API proporciona muchos métodos de acción web de API, idealmente me gustaría utilizar un atributo de autorización personalizado

public class ApiAuthorizationFilter : AuthorizeAttribute { protected override bool IsAuthorized(HttpActionContext actionContext) { return false; } }

¿Cómo puedo acceder a los datos de publicación / obtención de actionContext?

EDITAR: Ejemplo de POST

POST /Api/api/ActionMethod/ HTTP/1.1/r/n Content-Type: application/json/r/n Host: localhost/r/n Accept: */*/r/n Content-Length:52/r/n /r/n {"Id": ''121a222bc'', "Time": ''2012-02-02 12:00:00''}/r/n

¡Que tengas un buen día!


Aunque esta pregunta ya ha sido respondida. Pero en caso de que alguien más lo necesite, puede obtener las cadenas de consulta de ActionFilterAttribute como a continuación:

public class ApiAuthorizationActionFilter : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { var queryParameters = actionContext.Request.GetQueryNameValuePairs().ToDictionary(x => x.Key, x => x.Value); var some_value = queryParameters.ContainsKey("some_key") ? queryParameters["some_key"] : string.Empty; // Log Action Filter call base.OnActionExecuting(actionContext); } }

Pero, por lo general, la forma en que creo las autorizaciones de API usa encabezados y una lógica de verificación personalizada al agregar claves (cadenas exclusivas) a la base de datos contra usuario / cliente, etc.

public class ApiAuthorizationActionFilter : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { var headers = actionContext.Request.Headers.ToDictionary(x => x.Key, x => x.Value); string api_key = headers.ContainsKey("api_key") ? headers["api_key"].FirstOrDefault() : null; bool canAccessApi = IsValidKey(api_key); if (!canAccessApi) actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "You do not have access to this API. Please use a valid key."); // Log Action Filter call base.OnActionExecuting(actionContext); } private bool IsValidKey(string api_key) { //Build Access Control Logic here using database keys... return true; } }


Debería poder obtener esta información de actionContext.Request Esa es la manera de llegar a los datos de solicitud.

Los datos publicados se encuentran en actionContext.Request.Content O, si se trata de una solicitud GET, puede obtener la cadena de consulta de actionContext.Request.RequestUri


Debido a su naturaleza, AuthoriseAttribute parece que se llama en la tubería antes de que se hayan ejecutado los enlaces de modelo y los enlaces de parámetros. También te encuentras con problemas cuando accedes al Request.Content y lees de él ... esto solo se puede hacer una vez y si vas a probarlo en tu atributo auth puedes romper el mediaTypeFormater ...

en WebAPI, el cuerpo de la solicitud (un HttpContent) puede ser una secuencia de solo lectura, infinita, sin búfer y no rebobinable.

Actualización Hay diferentes formas de especificar el contexto de ejecución ... http://msdn.microsoft.com/en-us/library/system.web.http.filters.filterscope(v=vs.108).aspx . AuthoriseAttribute es "Global" y, por lo tanto, se golpea demasiado pronto para acceder a la información de acción.

Dado que desea acceder al modelo y a los parámetros, puede cambiar ligeramente su enfoque y usar un filtro OnActionExecuting (ámbito de filtro "Acción") en su lugar y lanzar un 401 o 403 en función de su validación.

Este filtro se llama más adelante en el proceso de ejecución y, por lo tanto, tiene acceso completo a los datos enlazados.

Un ejemplo muy simple a continuación:

public class ApiAuthorizationFilter : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { Foo model = (Foo)actionContext.ActionArguments["model"]; string param1 = (string)actionContext.ActionArguments["param1"]; int param2 = (int)actionContext.ActionArguments["param2"]; if (model.Id != "1") throw new HttpResponseException(System.Net.HttpStatusCode.Forbidden); base.OnActionExecuting(actionContext); } }

Controlador de ejemplo:

public class Foo { public string Id { get; set; } public DateTime Time { get; set; } } public class FoosController : ApiController { // PUT api/foos/5 [ApiAuthorizationFilter] public Foo Put(int id, Foo model, [FromUri]string param1 = null, int? param2 = null) { return model; } }

Lo que las otras respuestas decían ... tienen razón, si puedes acceder a todo lo que necesitas en la URL, obtén cosas a través de la solicitud; sin embargo, creo que el modelo y el contenido de la solicitud deben dejarse en paz:

var queryStringCollection = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query); //example for param1 string param1 = queryStringCollection["param1"]; //example for param2 int param2 = int.Parse(queryStringCollection["param2"]); //Example of getting the ID from the URL var id = actionContext.Request.RequestUri.Segments.LastOrDefault();


Puede acceder a los valores de cadena de consulta desde su atributo de autorización personalizado utilizando el siguiente código:

public class ApiAuthorizationFilter : AuthorizeAttribute { protected override void OnAuthorization(AuthorizationContext filterContext) { var querystring = filterContext.RequestContext.HttpContext.Request.QueryString; // Do what you need } }