On Asp.net Web Api authorization filters, how can I access to parameters?

醉酒当歌 提交于 2019-12-20 10:34:56

问题


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


回答1:


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__"];

    }



回答2:


Another alternative to get to the parameters is to Execute the binding for the parameters.

try
{
    var binding = actionContext.ActionDescriptor.ActionBinding;
    var parameters = binding.ParameterBindings.OfType<ModelBinderParameterBinding>();
    var newBinding = new HttpActionBinding(actionContext.ActionDescriptor, parameters.ToArray());
    newBinding.ExecuteBindingAsync(actionContext, new CancellationToken());
    var id = actionContext.ActionArguments["id"] as string;
}
catch
{
    base.HandleUnauthorizedRequest(actionContext);
}

Note: You need to make sure you only filter on the parameters that will come from the Request URI, as I have noticed that executing the binding for any parameters that are expected to come from the Request body will no longer be passed on to the actual action. i.e. those parameters will be null.

This is just to note that you can do this, I'd recommend using GetRouteData()/RouteData as it is not likely to disrupt the further flow of ASP.NET MVC modelbinding.

var routeData = actionContext.ControllerContext.RouteData;
var id = routeData.Values["id"] as string;


来源:https://stackoverflow.com/questions/16053732/on-asp-net-web-api-authorization-filters-how-can-i-access-to-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!