Authorization

Authorization happens later in the pipeline, closer to the controller. That lets you make more granular choices when you grant access to resources.

  • Authorization filters run before the controller action. If the request is not authorized, the filter returns an error response, and the action is not invoked.
  • Within a controller action, you can get the current principal from the ApiController.User property. For example, you might filter a list of resources based on the user name, returning only those resources that belong to that user.

 

Using the [Authorize] Attribute

Web API provides a built-in authorization filter, AuthorizeAttribute. This filter checks whether the user is authenticated. If not, it returns HTTP status code 401 (Unauthorized), without invoking the action.

You can apply the filter globally, at the controller level, or at the level of individual actions.

Globally: To restrict access for every Web API controller, add the AuthorizeAttribute filter to the global filter list:

C#Copy

public static void Register(HttpConfiguration config)
{
    config.Filters.Add(new AuthorizeAttribute());
}

Controller: To restrict access for a specific controller, add the filter as an attribute to the controller:

C#Copy

// Require authorization for all actions on the controller.
[Authorize]
public class ValuesController : ApiController
{
    public HttpResponseMessage Get(int id) { ... }
    public HttpResponseMessage Post() { ... }
}

Action: To restrict access for specific actions, add the attribute to the action method:

C#Copy

public class ValuesController : ApiController
{
    public HttpResponseMessage Get() { ... }

    // Require authorization for a specific action.
    [Authorize]
    public HttpResponseMessage Post() { ... }
}

Alternatively, you can restrict the controller and then allow anonymous access to specific actions, by using the [AllowAnonymous] attribute. In the following example, the Post method is restricted, but the Get method allows anonymous access.

C#Copy

[Authorize]
public class ValuesController : ApiController
{
    [AllowAnonymous]
    public HttpResponseMessage Get() { ... }

    public HttpResponseMessage Post() { ... }
}

In the previous examples, the filter allows any authenticated user to access the restricted methods; only anonymous users are kept out. You can also limit access to specific users or to users in specific roles:

C#Copy

// Restrict by user:
[Authorize(Users="Alice,Bob")]
public class ValuesController : ApiController
{
}
   
// Restrict by role:
[Authorize(Roles="Administrators")]
public class ValuesController : ApiController
{
}

Custom Authorization Filters

To write a custom authorization filter, derive from one of these types:

  • AuthorizeAttribute. Extend this class to perform authorization logic based on the current user and the user's roles.
  • AuthorizationFilterAttribute. Extend this class to perform synchronous authorization logic that is not necessarily based on the current user or role.
  • IAuthorizationFilter. Implement this interface to perform asynchronous authorization logic; for example, if your authorization logic makes asynchronous I/O or network calls. (If your authorization logic is CPU-bound, it is simpler to derive from AuthorizationFilterAttribute, because then you don't need to write an asynchronous method.)

The following diagram shows the class hierarchy for the AuthorizeAttribute class.

Authorization Inside a Controller Action

In some cases, you might allow a request to proceed, but change the behavior based on the principal. For example, the information that you return might change depending on the user's role. Within a controller method, you can get the current principal from the ApiController.User property.

C#Copy

public HttpResponseMessage Get()
{
    if (User.IsInRole("Administrators"))
    {
        // ...
    }
}