.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
}
}