6

I am trying to secure asp.net web-api 2.0 with Windows Identity Foundation 2. The choice I have to make is between role based authorization and claims based authorization. As a practice, I added a users in DbInitializer and assigned him two roles (Admin and Manager). When I log in with that user, I see that ClaimsPrincipal in debug mode, it already has those roles (Admin and Manager) associated as claims. So here are the questions:

  1. If roles are also treated as claims, what is the difference b/w roles and claims then?

  2. If I keep away from roles, how can I use claims to protect web api controllers and associated action methods. Like, I have an orders controller containing CRUD methods. I want one user (say a manager) to have access to Create and Get method and the second user (an admin) to have access to all those methods.

    How would I do that? with role based system, I would simply decorate the action methods with appropriate Authorize(Role = "Admin") attribute. How would I manage the claims itself? do I need to add them in database and grant/revoke those claims to different users through my application?

Community
  • 1
  • 1
Muhammad Adeel Zahid
  • 17,474
  • 14
  • 90
  • 155

1 Answers1

8

In principal there is no massive difference between Role and a Claim. I've been all hooked up for Claims-based authorisation, done a lot of research and a few test projects. And at the end of the day it all down to you to decide which one is to use.

As you said, roles are added as type of claims. So in delivery terms it makes no difference. But MVC/WebApi already have built-in infrastructure to handle roles and deny if user does not have the required role. So you won't have to do much yourself.
But you'll have to come up with a bunch of attributes on controllers/actions and make sure all of them exist in DB, so users can be assigned to them.

However I found that you can have too many roles and they become too much of a burden to maintain. Also you can't have too many roles assigned to your user - their authentication cookie will become massive and eventually will have to be unable to login due to cookie size limitation in browsers (4K per cookie, 16K for all HTTP headers).

With claims you can be more flexible. You can have many different types of claims (we have a bit less than one per controller) and a few claim values (Read, Create, Edit, Delete). With a descent sized application (we have above 100) you'll have to have a LOT of roles (4 per controller) to model this level of permission control. With claims we have an enum for claim types (Person, Product, Order) and enum for claim values (Create, Read, Edit, Delete). And in cookie you can set integers as a claim type and claim value - that saves a lot of space on authentication cookie.

But with claims you'll have to code the authentication mechanisms yourself.

I've been playing with this concept here and this is authentication filter for MVC, but WebApi filter will look very similar. Now results of this prototype are in production and working very well.

Overall, the answer to your question is "it depends". Mostly on how granular the authentication have to be and how big is the application.

trailmax
  • 34,305
  • 22
  • 140
  • 234
  • If I understand it correctly, claims give more granular control for authorization than roles. Like if I want to allow user to read orders, I will grant him a claim over Orders resource for read only? So, If I go with claims Identity, I will have to store claims for a particular user in Identity db and when he logs in, all the claims for user will be fetched from db and added to auth cookie? do I get it correctly? – Muhammad Adeel Zahid Dec 18 '14 at 06:55
  • I have downloaded your sample from git and exploring the code. I failed to find `Seed` method where you are populating database with startup data? – Muhammad Adeel Zahid Dec 18 '14 at 08:38
  • em.. I don't do seed there. Start the app and go register to create users. – trailmax Dec 18 '14 at 09:32
  • Yes, you understand it correctly. Claims can give you a better flexibility in terms of granularity of permissions; claims make it easier to model very (per action) granular permission. However you can do just the same with roles, but it might be more problematic to model over a large code-base. And yes, when claim is persisted in DB, it is automatically added into auth-cookie. – trailmax Dec 18 '14 at 09:35
  • There are already some users present in the db as I download it – Muhammad Adeel Zahid Dec 18 '14 at 13:08
  • One more question: u have added roles and RoleClaims entity and managed claims for roles rather than users. Any reason for not giving claims to users directly? – Muhammad Adeel Zahid Dec 18 '14 at 13:09
  • Uh.. yeah, possible that users are there. I committed the DB every time I played with it. It's a play-project. Random type of junk you can find there -) We have hundreds of users within groups of responsibility. It was easier to manage claims by roles than by users, that's all - just big user-base. – trailmax Dec 18 '14 at 14:28
  • This answer doesn't make it sound much different than roles + permissions. Where roles are used for ui and assignment, authorization is airways done against the aggregate of all permissions related to the assigned roles. It is perhaps a bit more elegant. Although I would still use roles as a container for claims because u don't want a user account screen with hundreds of claims to choose from – Sam Mar 23 '15 at 22:30
  • @trailmax u said roles are added in auth cookie but it is not mandatory. we can store the userid in auth cookie and by custom auth we can extract user id from auth cookie and load user roles from db based on user id. see this link http://www.codeproject.com/Articles/578374/AplusBeginner-27splusTutorialplusonplusCustomplusF – Monojit Sarkar Sep 21 '16 at 12:08
  • @trailmax would u tell me why some one will put the roles name or id in auth cookie. where u have seen this approach. can u give a link for this? – Monojit Sarkar Sep 21 '16 at 12:09
  • @MonojitSarkar what you link to is referring to MembershipProvider - that is outdated. I'm talking about Asp.Net Identity framework. And it adds roles, etc on cookie in it's source code: http://aspnetidentity.codeplex.com/SourceControl/latest#src/Microsoft.AspNet.Identity.Core/ClaimsIdentityFactory.cs see `CreateAsync` method. – trailmax Sep 21 '16 at 13:22