I'am starting with Asp.Net Web API and here's my problem :
I implement a custom authorization filter to inspect my message header looking for an API Key. Based on this API Key, I retrieve my user and then I would like to see if he can have access to some resources. The resources ID I want to check is on the parameters of the HTTP request. But when I'am on the AuthorizationFilter method, the actions parameters list is empty.
How can I do that ?
If I used an ActionFilter in replacement of an authorization filter, how can I be sure that this will be the first filter executed ? And globally, how can I specify the executing order of filters ?
Last question, is it possible to add some data "on the pipe" that I could retrieve on any filter ? Something like a session store but limited to the request ?
Thanks for any response
Authorization should be done by an authorization filter or inside the controller action. Here is the flow in the Web API 2 pipeline: Before invoking an action, Web API creates a list of the authentication filters for that action. This includes filters with action scope, controller scope, and global scope.
In Web API, authentication filters handle authentication, but not authorization. Authorization should be done by an authorization filter or inside the controller action. Before invoking an action, Web API creates a list of the authentication filters for that action. This includes filters with action scope, controller scope, and global scope.
Authentication Filters in ASP.NET Web API 2. An authentication filter is a component that authenticates an HTTP request. Web API 2 and MVC 5 both support authentication filters, but they differ slightly, mostly in the naming conventions for the filter interface.
Web API Filters. Web API includes filters to add extra logic before or after action method executes. Filters can be used to provide cross-cutting features such as logging, exception handling, performance measurement, authentication and authorization.
The authorization attributes run before parameter binding has run therefore you cannot (as you have seen) use the ActionArguments
collection. Instead you will need to use the request uri for query parameters and route data for uri parameters as demonstrated below.
//request at http://localhost/api/foo/id?MyValue=1
public class MyAuthorizationAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext)
{
//will not work as parameter binding has not yet run
object value;
actionContext.ActionArguments.TryGetValue("id", out value);
//Will get you the resource id assuming a default route like /api/foo/{id}
var routeData = actionContext.Request.GetRouteData();
var myId = routeData.Values["id"] as string;
//uri is still accessible so use this to get query params
var queryString = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query);
var myQueryParam = queryString["MyValue"];
//and so on
}
}
About the execution order:
There are 3 different ways of specifying the execution order of filters using the FilterScope Enumeration... scope being Global, Controller and Action. The AuthoriseAttribute
is "Global" and therefore it
Specifies an action before Controller.
If you needed to specify the execution order within these 3 scopes then you should read this blog article here where you will need to implement a FilterProvider
To add some data to the pipe:
Use the properties collection on the request this collection is available for the duration of the request.
protected override bool IsAuthorized(HttpActionContext actionContext)
{
actionContext.Request.Properties.Add("__MYKEY__","MyValue");
//access this later in the controller or other action filters using
var value = actionContext.Request.Properties["__MYKEY__"];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With