Accessing post or get parameters in custom authorization MVC4 Web Api

Due to its nature the AuthoriseAttribute looks like it is called in the pipeline before the model binders and parameter bindings have run. You also run into issues when you access the Request.Content and read from it… this can only be done once and if you are going to try it in your auth attribute you may break the mediaTypeFormater…

in WebAPI, the request body (an HttpContent) may be a read-only, infinite, non-buffered, non-rewindable stream.

Update
There are different ways of specifying the execution context… http://msdn.microsoft.com/en-us/library/system.web.http.filters.filterscope(v=vs.108).aspx. The AuthoriseAttribute is “Global” and therefore it is hit too early to access the action information.

Given you want access to the model and parameters you can change your approach slightly and use an OnActionExecuting filter (“Action” filter scope) instead and throw a 401 or 403 based on your validation.

This filter is called later in the execution process and you therefore have full access to the bound data.

Very simple example below:

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);
    }
}

Example controller:

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

What the other answers were saying…. they are right you can, if you can access all you need on the URL, get at stuff via the request; however, I think the model and the request content should be left alone:

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();

Leave a Comment