Role-based access control (RBAC) vs. Claims-based access control (CBAC) in ASP.NET MVC
I will try to show how you can benefit from Claim Based Access Control in an ASP.NET MVC Context.
When you are using Role based authentication, if you have an action for creating customer and you want that the people who are in 'Sale' role should be able to do that, then you write code like this:
[Authorize(Roles="Sale")]
public ActionResult CreateCustomer()
{
return View();
}
Later, you realized that, sometimes, people from 'Marketing' role should be able to create Customer. Then, you update your Action method like that
[Authorize(Roles = "Sale", "Marketing")]
public ActionResult CreateCustomer()
{
return View();
}
Now, you realized that, some of the marketing people must not be able to create Customer, but it is not possible to assign a different role for those people who are in Marketing. So, you are forced to allow all marketing people to create Customers.
you spotted another problem, anytime you decide that Marketing people should be allowed to create customers, you have to update all of your MVC Action methods Authorize attribute, compile your application, test and deploy. Some days later, you decided, not marketing but some other role should be allowed to do the task, so you search in your codebase and delete all 'Marketing' from Authorize attribute and add your new role name in Authorize attribute... Not a healthy solution. At that point, you would realize a need for Permission Based Access Control.
Permission Based access control is a way of assigning various permissions to various users and checking if a user has permission to execute an action from the code in run time. After you assign various permissions to various users, you realize that you need to allow some users to execute some code if the user has some property like "Facebook User", "Long time User" etc. Let me give an example. Say you want to allow access to a specific page if the user is logged in using Facebook. Now, would you create a permission 'Facebook' for that user ? No, 'Facebook' does not sound like a permission. Does it ? Rather it sounds like a claim. At the same time, Permissions can sound like Claim too !! So, it is better to check for claims and allow access.
Now, lets go back to the concrete example of claim based access control.
You can define some set of claims like this :
"CanCreateCustomer", "CanDeleteCustomer", "CanEditCustomer".. etc..
Now, you can decorate your Action Method like this:
[ClaimAuthorize(Permission="CanCreateCustomer")]
public ActionResult CreateCustomer()
{
return View();
}
(please note, [ClaimAuthorize(Permission="CanCreateCustomer")] may not be built into MVC class library, I am just showing as an example, you can use some class library which has such Attribute class definition)
Now, you can see that, CreateCustomer action method will always need permission 'CanCreateCustomer' and it will never change or hardly change. So, in your database, you create a table of permissions (claims) and user-permission relation. From your admin panel, you can set permission (claim) for each user who can do what. You can assign 'CanCreateCustomer' permission (claim) to anyone you like and only permitted user will be able to create customer and permitted user will be able to create only customer and nothing else (unless you assign other permissions to the same user).
This security model offers you clean code practice. Moreover, when you write your Action Method, you dont have to think about who can use this method, rather you can always be assured that whoever is using this method will have proper permission (claim) given by the Admin. Then, Admin can decide who will be able to do what. Not you as a developer. Thats how your business logic is separated from Security logic.
Whenever someone signs in, your application will check whatever permissions are available for that user and that permission (claim) set will be available as additional properties of currently logged in user (usually the claim set is stored as cookie for the logged in user), so you don't have to check permission set all the time from database. The bottom line is, you get more control of your security logic in your application if you apply claim based access rather than role based access. In fact, a Role can be considered as a Claim too.
If your application is a very little application where there would be only 2 roles : Customer and Admin and there is no chance that Customer will be able to do anything else other than what they are meant to do in your application, then perhaps, Role based access control will serve the purpose, but as your application grows, you will start to feel the need of claim based access control at some point.
I have implemented security models many times now and have had to wrap my head around these concepts as well. Having done it many times, here is my understanding of these concepts.
What Are Roles
Role = The union of Users and Permissions.
On one hand, a Role is a collection of Permissions. I like to call it a Permission Profile. When defining a Role you basically add a bunch of Permissions into that Role so in that sense a Role is a Permission Profile.
On the other hand, a Role is also a collection of Users. If I add Bob and Alice to the Role "Managers" then "Managers" now contains a collection of two Users sort of like a Group.
The truth is that a Role is BOTH a collection of Users and a collection of Permissions put together. Visually this can be viewed as a Venn diagram.
What is a Group
Group = Collection of Users
A "Group" is strictly a collection of Users. The difference between a Group and a Role is that a Role also has a collection of Permissions but a Group only has a collection of Users.
What is a Permission
Permission = What a subject can do
What is a Permission Set
Permission Set = A Collection of Permissions
In a robust RBAC system, Permissions can also be grouped like Users. Whereas Groups are a collection of Users only, a Permission Set is a collection of Permissions only. This allows an administrator to add whole collections of Permissions to Roles at one time.
How Users, Groups, Roles, and Permissions Come Together
In a robust RBAC system, Users can be added to a Role individually to create the collection of Users in the Role or Groups can be added to a Role to add a collection of Users to the Role at one time. Either way, the Role gets its collection of Users from being individually added or by adding Groups to the Role or by adding a mix of Users and Groups to the Role. Permissions can be thought of in the same way.
Permissions can be added to Roles individually to create the collection of Permissions inside the Role or Permission Sets can be added to a Role. Finally, a mix of Permissions and Permission Sets can be added to a Role. Either way, the Role gets its collection of Permissions from being individually added or by adding Permission Sets to a Role.
The whole purpose of Roles is to marry Users to Permissions. Therefore, a Role is the UNION of Users and Permissions.
What Are Claims
Claim = What a Subject "is"
Claims are NOT Permissions. As pointed out in previous answers, a Claim is what a subject "is" not what a subject "can do".
Claims do not replace Roles or Permissions, they are additional pieces of information that one can use to make an Authorization decision.
When to Use Claims
I have found Claims to be useful when an Authorization decision needs to be made when the User cannot be added to a Role or the decision is not based on the association of User to Permission. The example of a Facebook User causes this. A Facebook User may not be someone who is added to a "Role" ... they are just some Visitor authenticated through Facebook. Though it doesn't fit neatly into RBAC it is a piece of information to make a authorization decision on.
@CodingSoft used the night club metaphor in a previous answer, which I'd like to extend. In that answer, the Driver's License was used as an example that contained a set of Claims where the Date of Birth represents one of the Claims and the value of the DateOfBirth Claim is used to test against the authorization rule. The government that issued the Driver's License is the authority that gives the Claim authenticity. Therefore, in a night club scenario, the bouncer at the door looks at the the person's Driver's License, ensures that it was issued by a trusted authority by examining whether or not it is a fake ID (i.e. must be valid government issued ID), then looks at the Date of Birth (one of the many claims on a Driver's License), then uses that value to determine if the person is old enough to enter the club. If so, the person passes the authorization rule by virtue of having a valid Claim, not by being in some Role.
Now, with that base in mind I'd like to now extend that further. Suppose that the building where the night club is contains offices, rooms, a kitchen, other floors, elevators, a basement, etc. where only employees of the club can enter. Furthermore, certain employees might have access to certain places that other employees may not. For example, a Manager may have access to an office floor above that other employees cannot access. In this case there are two Roles. Manager and Employee.
While visitors' access to the public night club area is authorized by a single claim as explained above, employees need access by Role to other non-public restricted rooms. For them, a Driver's License is not enough. What they need is an Employee Badge that they scan to enter doors. Somewhere there is an RBAC system that grants badges in the Manager Role access to the top floor, and badges in the Employee Role access to other rooms.
If for whatever reason certain rooms need to be added/removed by Role, this can be done using RBAC, but it is not a good fit for a Claim.
Permissions in Software
Coding Roles into the application is a bad idea. This hard codes the purpose of the Role into the application. What the application should have is just Permissions that act like Feature Flags. Where Feature Flags are made accessible by configuration, Permissions are made accessible by the User Security Context that is derived by the DISTINCT collection of Permissions gathered from all Roles the User has been placed in. This is what I call the "Effective Permissions." The application should only present a menu of possible Permissions to features / actions. The RBAC system should do the job of marrying those Permissions to Users through Roles. This way, there is no hard coding of Roles and the only time a Permission changes is when it is removed or a new one is added. Once a Permission is added to the software it should never be changed. It should only be removed when necessary (i.e. when a feature is discontinued in a new version) and only new ones can be added.
One final note.
Grant vs Deny
A robust RBAC system and even a CBAC system should distinguish between Grants and Denials.
Adding a Permission to a Role should come with either a GRANT or a DENY. When Permissions are checked, all GRANTed Permissions should be added to the Users list of Effective Permissions. Then after all that is done, a list of DENIED Permissions should cause the system to remove those Permissions from the list of Effective Permissions.
This allows administrators to "tweak" the final Permissions of a subject. It is best if Permissions can also be added to Users directly. This way, you can add a User to a Manager Role and they get access to everything, but perhaps you want to DENY access to the Lady's Restroom because the User is a male. So you add the male User to the Manager Role, and add a Permission to the User object with DENY so it takes away only that Lady's room access.
Actually, this would be a good candidate for a Claim. If the User has a Claim "gender=male", then being in the Manager Role gives access to all rooms but the Lady's restroom also requires the Claim gender=female and the Men's restroom requires Claim gender=male. In this way one would not have to configure a DENY permission to male Users since the Claim enforcement takes care of that for everyone with a single authorization rule. However, it could be done either way.
The point is that with DENIAL of Permissions it makes the management of the Roles easier because exceptions can be implemented.
Below is a diagram I made a long time ago that shows the RBAC model. I don't have a graphic for the Claims but you can imagine they are just attributes attached to the Users wherever they are. Also, the diagram doesn't show Groups (I need to update it at some point).
I hope this helps.
This is a Diagram of the RBAC Described Above
Update on April 7, 2019 Based on feedback from @Brent (thank you) ... removed unnecessary references to previous answers and explained the original basis of the "night club" metaphor provided by @CodingSoft in order to make this answer understandable without having to read other answers.
I don't fully agree with Emran's answer
[Authorize(Roles="Sale")]
Is naive
The question is how
[Authorize(Roles="CustomerCreator")]
is different from
[ClaimAuthorize(Permission="CanCreateCustomer")]
If both are equally good, why we need claim ?
I think because
Claims concept is more generic compared to Role
In context of the example above we can say "CustomerCreator" is a claim of type "role" provided by "Asp.NETroleProvider"
Additional examples of claims.
"AAA" is claim of type "MYExamSite.Score" provided by "MYExamSite.com"
"Gold" is claim of type "MYGYM.Membershiptype" provided by "MYGYMApp"