In many systems out there on the web today who rely on APIs as their backbone for data delivery, authorization can become a tricky business. And it used to be a very tricky business. But now that there are standards in place that specify how identity should be issued on the world wide web, it has become more and more easier for architects and software engineers to decouple their systems in such a way, that APIs & servers are mainly responsible for serving, and maintaining data. And where the clients of those servers are mainly responsible for data consumption, and manipulation. You can think of the clients as acting upon resources which the API has dominion over.
So it should come as no surprise that the ASP.NET Core team has put a lot of thought an effort into this. And the folks at Microsoft have given us the right abstractions for how to do API authorization in a sane manner that does not add a huge clunk of clutter to your controllers. For simplicity sake I will briefly describe each of them that matter for APIs in ASP.NET Core.
In a nutshell, your request is challenged if the principle is anonymous. That is what simple authorization is.
Claims Based Authorization
Basically authorization based on the claims of the principle. eg does the user have a
role claim of
Policy Based Authorization
This authorization abstraction basically allows you to do more complex assertions on the users’ claims. For instance, you could have a policy named
IsPensioner that checks to see if the user is older than 65 based on the users
Resource Based Authorization
This will be the bulk of this blog post. The basic premise of resource based authorization is based on weather or not the principle do an action on a resource.
The nice things about the the former three are that they are declarative from the controllers perspective. Because of the declarative nature of claims based and policy based authorization, you can chain these policies together such that you can have an authorization criteria that chains on multiple policies, under the hood claims based authorization is actually a simplified form of policy based authorization in ASP.NET Core. In contrast, resource based authorization is imperative. Which means that the it is up to the developer as to when and where they want to do authorization within the application itself.
Lets paint a scenario that can form the analog basis to a swath of authorization considerations. We have an API where users can submit posts. The posts are owned by the user who made the post , if a user owns a resource, it means they can manipulate the resources as they see fit. But for moderation reasons we would also like the possibility for the moderators to have “ownership” over these resources. By ownership, I mean that moderators can edit or delete posts of any users even if the resource does not belong to them. Basically the action requirements are no different to that of a public forum. Lets just say as a rule we allow anyone to read the posts (as long as they pass basic authorization). So we do not need any form of role based authorization here.
So we can define our post resource as follows:
and with that we can define a separate model that is of concern to the authorization handler.
This is not required but I like to separate out the models so that only required information gets handed to the authorization handler.
And then we can define the operations that we want to describe on the resource.
And finally the handler that implements
IAuthorizationHandler that will do the assertions on the resource based on the principle in the request context.
All we need to do is put this into an API controller and we have ourselves resource based authorization.
And there we have it. For every HTTP action that works on a resource, we have an authorization handler that allows the owner of the resource or a moderator to do the action we have .Basically authorization will be handled within the appropriate handler, which means you can separate those concerns away from your controller in a clean fashion.