Role-based access control (RBAC) vs. Claims-based access control (CBAC) in ASP.NET MVC

血红的双手。 提交于 2019-11-27 10:00:53

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 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.

  1. "AAA" is claim of type "MYExamSite.Score" provided by "MYExamSite.com"

  2. "Gold" is claim of type "MYGYM.Membershiptype" provided by "MYGYMApp"

The accepted answer appears to position Roles as a blunt object and Claims as a flexible tool, but otherwise makes them seem nearly identical. Unfortunately, this positioning does a disservice to the concept of claims and may fundamentally reflect a slight misunderstanding of their purpose.

Roles exist and make sense only within an implicit scope. Generally that is an application or organizational scope (i.e. Role=Administrator). Claims, on the other hand, can be 'made' by anyone. For example, Google authentication may produce claims including a user's "email", thus attaching that email to an identity. Google makes the claim, the application chooses whether to understand and accept that claim. The application itself might subsequently attach a claim called "authenticationmethod" (as ASP.NET MVC Core Identity does) with a value of "Google". Each claim includes a scope so that it's possible to identify whether a claim has meaning externally, locally, or both (or more fine grained as needed.)

The key points are that all claims are explicitly attached to an identity and include an explicit scope. Those claims may of course be used for authorization - and ASP.NET MVC provides support for that via the Authorize attribute, but that is not the only or necessarily even primary purpose for Claims. It certainly doesn't distinguish it from Roles, which can be used in exactly the same ways for locally scoped authorization.

So one can choose to use Roles, or Claims, or both for the purpose of authorization and likely find no inherent advantage or disadvantage to either, so long as those Roles and Claims are locally scoped. But if, for instance, authorization depends upon external identity claims, then Roles will be inadequate. You would have to accept the external claim and translate it into a locally scoped role. There isn't necessarily anything wrong with that, but it introduces a layer of indirection and discards context.

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.

More broadly, you should consider attribute-based access control (ABAC). RBAC and ABAC are both concepts defined by NIST, the National Institute of Standards and Technology. CBAC, on the other hand, is a model pushed by Microsoft which is very similar to ABAC.

Read more here:

Role is just one type of Claim. Like that, there can be many other claim types, for example user name is one of the claim type

The fundamental between RBAC and CBAC is that:

RBAC: a user must be assigned to a role to be authorized to perform an action.

CBAC : user must have a claim with the correct value, as expected by the application, to be authorized. Claims-based access control is elegant to write and easier to maintain.

Beside that claims are issued to the application by an issuing authorize services (Security Service Token STS) that is trusted by your application (Relying Party)

CodingSoft

It is important to first analyse what the Authentication is required for before deciding on which method is best. From Microsoft documentation below, it says "A claim is not what the subject can do. For example, you may have a driver's license, issued by a local driving license authority. Your driver's license has your date of birth on it. In this case the claim name would be DateOfBirth, the claim value would be your date of birth, for example 8th June 1970 and the issuer would be the driving license authority. Claims based authorization, at its simplest, checks the value of a claim and allows access to a resource based upon that value. For example if you want access to a night club the authorization process might be:6" The door security officer would evaluate the value of your date of birth claim and whether they trust the issuer (the driving license authority) before granting you access.

From this example we can see that accessing a nigh club with a Claims-Based Authorization is quit different from the type of Authorization that will be required by the staff who work in the night club, in this case the staff of the night club will require a Role based Authorization which is not required for the night club visitors as the night club visitors all have a common purpose at the night club hence in this situation a Claims-Based Authorization is suitable for the night club visitors.

Role based Authorization https://docs.microsoft.com/en-us/aspnet/core/security/authorization/roles 10/14/2016 When an identity is created it may belong to one or more roles. For example, Tracy may belong to the Administrator and User roles whilst Scott may only belong to the User role. How these roles are created and managed depends on the backing store of the authorization process. Roles are exposed to the developer through the IsInRole method on the ClaimsPrincipal class.

Claims-Based Authorization https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims 10/14/2016 When an identity is created it may be assigned one or more claims issued by a trusted party. A claim is name value pair that represents what the subject is, not what the subject can do. For example, you may have a driver's license, issued by a local driving license authority. Your driver's license has your date of birth on it. In this case the claim name would be DateOfBirth, the claim value would be your date of birth, for example 8th June 1970 and the issuer would be the driving license authority. Claims based authorization, at its simplest, checks the value of a claim and allows access to a resource based upon that value. For example if you want access to a night club the authorization process might be:

The door security officer would evaluate the value of your date of birth claim and whether they trust the issuer (the driving license authority) before granting you access.

An identity can contain multiple claims with multiple values and can contain multiple claims of the same type.

It is also possible to manages roles in a claims manner.

Instead of creating authorisation roles that reflect a business role, create roles that reflect action roles, e.g. CreateCustomer, EditCustomer, DeleteCustomer. Annotate methods as required.

It is not a simple matter to map individuals to a set of action roles, especially as the role list gets larger. Therefore, you'll need to manage the business roles at a lower level of granularity (e.g. Sales, Marketing) and map the business Role to the action roles required. I.e., add a user to a business role and it maps them to the required (action) roles in the existing authorisation table.

You can even override the business role and add a person to an action role directly.

Because you build on top of what already works, you don't undo the existing Authorisation process. You need only a few more tables to implement this approach

I think this question could be answered from the database prospective. if you noticed how the tables involved in this implantation you will find the following

  1. AspNetUsers : each user has one row with all the attributes required by all users like email, address phone, password.....
  2. AspNetRoles ; defines different roles as per application requirements like GM , CTO, HRM,ADMIN, EMP. what each roles defines is as per application needs.
  3. AspNetUserRoles: each row links AspNetUsers and AspNetRoles and effectively links between one user and many roles.
  4. AspNetUserClaims: each row has key to AspNetUsers and one type and value. so effectively add one attribute for each user that could be added/removed at run time.

The usage of this tables could be tweaked at one moment of user/application life time to match specific needs.

Consider the early stage of "Purchasing Manager" (PM), we could have three approachs

  1. Application populates AspNetUserRoles with one row to grants 'PM' right to buy. To issue purchasing order with any amount, user only need "PM" role.

  2. Application populates AspNetUserRoles with one row to grants 'PM' right to buy, and populates the AspNetUserClaims a claim of TYPE 'Purchasing Amount' type and "<1000" value to set the amount limit. To issue purchasing order, user need to has 'PM'and the order amount be less than claim value of claim TYPE 'Purchasing Amount'.

  3. Application populate AspNetUserClaims with claim of TYPE 'Purchasing Amount' type and "<1000" value. Any user can issue purchasing order, given the the amount to be less than claim value of claim TYPE 'Purchasing Amount' for this user.

As it could be noticed, role based is coarse grained of rigid rights that would simplify the life of the application user from the system management point of view. however it will limits the user abilities from the business requirements point of view. At the other hand claim based is very fine rights that need to be assigned to each user. claim based will push the business too the limit, however will make the system management very complex.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!