Authorization in ASP.NET Web API

So far I have mostly focused on authentication in Web API. At the end of the day you go through all those hoops just to be able to authorize the user after you know who he is.

I am currently toying around with some ideas how to improve authorization, but first things first – let’s have a look what’s built-in.

Enforce authentication
The most basic authorization check you might want to do is to make sure that a user is at least authenticated. This is achieved by adding an [Authorize] attribute on top of a controller or an action method. There is also the [AllowAnonymous] attribute with which you can exclude certain action methods from the authentication requirement.

If all you care about is that the user is successfully authenticated (or technically speaking his IsAuthenticated property is set to true), decorate the controller with [Authorize] and exclude (if needed) individual action methods with [AllowAnonymous]. This is much better than it used to be before MVC 4 (which was the other way round).

Keep in mind, that being authenticated might not be enough, especially when you are moving to a third party authentication model. This means that someone else does the authentication (maybe your business partner’s IdP or Google et al) and that this third party was able to authenticate the user. This does not necessarily mean that the user is also authorized to use your application (unless you want to create a free service for all Google users ;)). This is were authorization come into play.

Role-based Access Control
ASP.NET Web API is designed to run on both .NET 4.0 and 4.5 – since the least common authorization denominator between the two is roles-based access control, this is what we get out of the box.

There are two ways to do role checks, one is calling Thread.CurrentPrincipal.IsInRole(“foo”) from within your code. Or you decorate controllers and actions with [Authorize(Roles = “foo”)]. Both approaches check if the user is in a role called foo.

Custom Authorization Attribute
If you want more than simple IsAuthenticated or IsInRole checks, you can write your own authorization attribute and implement whatever logic you want. You just need to derive from AuthorizeAttribute and implement the IsAuthorized method.

public class PremiumUsersOnlyAttribute : AuthorizeAttribute

{

    protected override bool IsAuthorized(HttpActionContext context)

    {

        IPrincipal client = Thread.CurrentPrincipal;

        // custom authorization logic

    }

 

    protected override void HandleUnauthorizedRequest(
      HttpActionContext actionContext)

    {

        // custom response (default is 401)

    }

}

 

You would then decorate your controllers/actions with this new attribute.

Note: This code does not work with the RC bits. It will work with RTM (and does already work with the Codeplex bits).

That’s everything there is out of the box in Web API. In the following posts I will explore some fundamental approaches to authorization and how they can be implemented using the Web API extensibility.

This entry was posted in WebAPI. Bookmark the permalink.

3 Responses to Authorization in ASP.NET Web API

  1. Pingback: Extending Authorization in ASP.NET Web API – Part 1: Basics | www.leastprivilege.com

  2. Pingback: SessionToken and WebAPI Authorization now in Thinktecture.IdentityModel.40 « brockallen

  3. You’ve described this in a way that lets even a C# simpleton understand it. And there was I trotting off to write my own provider from the ground up. All other tutorials I’ve read so far have been written in some weird foreign language. Thank you. You’ve saved me several days of reinventing the wheel.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s