使用CBAC与RBAC的主要好处是什么?什么时候使用CBAC更好,什么时候使用RBAC更好?
我试图理解CBAC模型的一般概念,但总体思想对我来说仍然不清楚。
使用CBAC与RBAC的主要好处是什么?什么时候使用CBAC更好,什么时候使用RBAC更好?
我试图理解CBAC模型的一般概念,但总体思想对我来说仍然不清楚。
当前回答
我将尝试用外行的术语解释基于角色/声明/权限的访问控制概念。我将在这里展示的代码片段是伪代码,可以编译也可以不编译。
什么是角色?
角色可以被认为是工作头衔。比如“销售经理”、“市场经理”、“行政”等等。
索赔是什么?
声明可以比角色更广泛。您可以将Claim看作一个TAG。例如,你可以给一个人贴上“友好”、“健谈”、“欧洲人”、“摄影师”、“18岁的成年人”等标签。从技术上讲,角色也可以被认为是一种要求。
基于角色的访问控制
非常简单。不使用文字,让我们看一些例子。 假设,您允许通过检查角色访问网站上的某些页面。是这样的:
[Authorize(Roles="Sales Manager")]
public ActionResult CreateCustomer()
{
return View();
}
[Authorize(Roles="Marketing Manager")]
public ActionResult EditLandingPage()
{
return View();
}
基于声明的访问控制
通俗地说,在基于声明的访问控制中,您在确定对页面的访问时检查声明而不是角色。
(这是一个伪代码。ClaimsAuthorize不是MVC中的内置类,相反,你可以找到一些NuGet包,或者你可以自己写)
[ClaimsAuthorize(Claims="Senior-Employee, Award-Winner-Employee, Experienced-On-Sales")]
public ActionResult CreateCustomer()
{
return View();
}
[ClaimsAuthorize(Claims="Trust-worthy-Employee, President")]
public ActionResult DeleteCustomer()
{
return View();
}
[ClaimsAuthorize(Claims="Adult-over-18years")]
public ActionResult ViewImagesOfViolence()
{
return View();
}
请注意,我们允许根据用户声称的WHO访问页面,而不是检查角色。
RBAC vs CBAC
好的,现在,如果你问基于角色的访问控制或基于声明的访问控制有什么好处,那么,想想这个页面“ViewImagesOfViolence”。在决定是否允许用户访问该页面时,检查“18岁以上成年人”的声明不是更直观吗?总之,使用Claims,您可以在用户比较角色中创建更多段。从抽象的意义上讲,所有的角色都可以是声明,但是声明不能被认为是角色。
基于权限的访问控制
在允许权限查看页面时,您应该考虑基于权限的访问控制,而不是检查role或claim。让我给你看一些痛点。
当你使用基于角色的身份验证时,如果你有一个创建客户的动作,并且你希望处于“销售”角色的人应该能够做到这一点,那么你写这样的代码:
[Authorize(Roles="Sale")]
public ActionResult CreateCustomer()
{
return View();
}
后来,你意识到,有时候,来自“营销”角色的人应该能够创建客户。然后,像这样更新Action方法
[Authorize(Roles = "Sale", "Marketing")]
public ActionResult CreateCustomer()
{
return View();
}
现在,您意识到一些营销人员肯定不能创建客户,但不可能为这些营销人员分配不同的角色。所以,你不得不让所有的营销人员去创造客户。
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.
基于权限的访问控制是一种将各种权限分配给各种用户或各种角色或各种声明的方法,并检查用户是否具有在运行时从代码执行操作的权限。如果您将权限分配给角色或声明,那么,您将检查该登录用户的角色或声明是什么。然后,您将检查这些角色或声明有哪些权限可用。
你可以像这样定义一些权限集:
有顾客,有顾客,有顾客。等一下…
现在,你可以像这样装饰你的动作方法:
[Authorize(Permission="CanCreateCustomer")]
public ActionResult CreateCustomer()
{
return View();
}
请注意,[Authorize(Permission="CanCreateCustomer")]可能不会 被构建到MVC类库中,我只是作为一个抽象意义上的例子来展示。可以有一个NuGet包,它将在Authorize类中具有Permission属性。
现在,你可以看到,CreateCustomer操作方法总是需要CanCreateCustomer权限,它永远不会改变或几乎不会改变。
谁将获得许可?
您可以直接为用户分配一组权限。但是不要这样做。要做到这一点将非常困难。相反,
您可以为角色分配一组权限,也可以为Claim(推荐)分配一组权限。
正如我提到的,角色也可以被认为是要求。因此,您可以将角色视为声明。然后,您可以在数据库中创建一个Claims表。 然后,创建另一个表来保存每个声明可以包含多个权限的关系。
此安全模型为您提供了干净的代码实践。此外,当您编写Action方法时,您不必考虑谁可以使用此方法,而是始终可以确保使用此方法的任何人都具有管理员授予的适当权限。然后,管理员可以决定谁可以做什么。而不是作为开发者的你。这就是业务逻辑与安全性逻辑分离的方式。
每当有人登录时,您的应用程序将检查该用户可用的权限,该权限集将作为当前登录用户的附加属性可用,因此您不必一直从数据库中检查权限集。最重要的是,如果应用基于权限的访问控制,则可以更好地控制应用程序中的安全逻辑。
如果您的应用程序是一个非常小的应用程序,只有两个角色:客户和管理员,客户除了在应用程序中应该做的事情外,不可能做任何其他事情,那么简单的基于角色的访问控制可能会达到目的,但随着应用程序的增长,您将在某个时候开始感到需要基于权限的访问控制。
其他回答
我将尝试用外行的术语解释基于角色/声明/权限的访问控制概念。我将在这里展示的代码片段是伪代码,可以编译也可以不编译。
什么是角色?
角色可以被认为是工作头衔。比如“销售经理”、“市场经理”、“行政”等等。
索赔是什么?
声明可以比角色更广泛。您可以将Claim看作一个TAG。例如,你可以给一个人贴上“友好”、“健谈”、“欧洲人”、“摄影师”、“18岁的成年人”等标签。从技术上讲,角色也可以被认为是一种要求。
基于角色的访问控制
非常简单。不使用文字,让我们看一些例子。 假设,您允许通过检查角色访问网站上的某些页面。是这样的:
[Authorize(Roles="Sales Manager")]
public ActionResult CreateCustomer()
{
return View();
}
[Authorize(Roles="Marketing Manager")]
public ActionResult EditLandingPage()
{
return View();
}
基于声明的访问控制
通俗地说,在基于声明的访问控制中,您在确定对页面的访问时检查声明而不是角色。
(这是一个伪代码。ClaimsAuthorize不是MVC中的内置类,相反,你可以找到一些NuGet包,或者你可以自己写)
[ClaimsAuthorize(Claims="Senior-Employee, Award-Winner-Employee, Experienced-On-Sales")]
public ActionResult CreateCustomer()
{
return View();
}
[ClaimsAuthorize(Claims="Trust-worthy-Employee, President")]
public ActionResult DeleteCustomer()
{
return View();
}
[ClaimsAuthorize(Claims="Adult-over-18years")]
public ActionResult ViewImagesOfViolence()
{
return View();
}
请注意,我们允许根据用户声称的WHO访问页面,而不是检查角色。
RBAC vs CBAC
好的,现在,如果你问基于角色的访问控制或基于声明的访问控制有什么好处,那么,想想这个页面“ViewImagesOfViolence”。在决定是否允许用户访问该页面时,检查“18岁以上成年人”的声明不是更直观吗?总之,使用Claims,您可以在用户比较角色中创建更多段。从抽象的意义上讲,所有的角色都可以是声明,但是声明不能被认为是角色。
基于权限的访问控制
在允许权限查看页面时,您应该考虑基于权限的访问控制,而不是检查role或claim。让我给你看一些痛点。
当你使用基于角色的身份验证时,如果你有一个创建客户的动作,并且你希望处于“销售”角色的人应该能够做到这一点,那么你写这样的代码:
[Authorize(Roles="Sale")]
public ActionResult CreateCustomer()
{
return View();
}
后来,你意识到,有时候,来自“营销”角色的人应该能够创建客户。然后,像这样更新Action方法
[Authorize(Roles = "Sale", "Marketing")]
public ActionResult CreateCustomer()
{
return View();
}
现在,您意识到一些营销人员肯定不能创建客户,但不可能为这些营销人员分配不同的角色。所以,你不得不让所有的营销人员去创造客户。
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.
基于权限的访问控制是一种将各种权限分配给各种用户或各种角色或各种声明的方法,并检查用户是否具有在运行时从代码执行操作的权限。如果您将权限分配给角色或声明,那么,您将检查该登录用户的角色或声明是什么。然后,您将检查这些角色或声明有哪些权限可用。
你可以像这样定义一些权限集:
有顾客,有顾客,有顾客。等一下…
现在,你可以像这样装饰你的动作方法:
[Authorize(Permission="CanCreateCustomer")]
public ActionResult CreateCustomer()
{
return View();
}
请注意,[Authorize(Permission="CanCreateCustomer")]可能不会 被构建到MVC类库中,我只是作为一个抽象意义上的例子来展示。可以有一个NuGet包,它将在Authorize类中具有Permission属性。
现在,你可以看到,CreateCustomer操作方法总是需要CanCreateCustomer权限,它永远不会改变或几乎不会改变。
谁将获得许可?
您可以直接为用户分配一组权限。但是不要这样做。要做到这一点将非常困难。相反,
您可以为角色分配一组权限,也可以为Claim(推荐)分配一组权限。
正如我提到的,角色也可以被认为是要求。因此,您可以将角色视为声明。然后,您可以在数据库中创建一个Claims表。 然后,创建另一个表来保存每个声明可以包含多个权限的关系。
此安全模型为您提供了干净的代码实践。此外,当您编写Action方法时,您不必考虑谁可以使用此方法,而是始终可以确保使用此方法的任何人都具有管理员授予的适当权限。然后,管理员可以决定谁可以做什么。而不是作为开发者的你。这就是业务逻辑与安全性逻辑分离的方式。
每当有人登录时,您的应用程序将检查该用户可用的权限,该权限集将作为当前登录用户的附加属性可用,因此您不必一直从数据库中检查权限集。最重要的是,如果应用基于权限的访问控制,则可以更好地控制应用程序中的安全逻辑。
如果您的应用程序是一个非常小的应用程序,只有两个角色:客户和管理员,客户除了在应用程序中应该做的事情外,不可能做任何其他事情,那么简单的基于角色的访问控制可能会达到目的,但随着应用程序的增长,您将在某个时候开始感到需要基于权限的访问控制。
在决定哪种方法是最好的之前,首先分析身份验证需要什么是很重要的。来自基于声明的授权:
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: 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.
从这个例子我们可以看到,使用声明式授权访问几乎俱乐部退出不同的授权类型需要的员工在夜总会工作,在这种情况下,员工俱乐部需要一个基于角色的授权而不是必需的夜总会游客的夜总会的游客都有一个共同的目的在夜总会因此在这种情况下的声明式授权适用于夜总会游客。
来自基于角色的授权:
当创建一个标识时,它可能属于一个或多个角色。例如,Tracy可能属于管理员和用户角色,而Scott可能只属于用户角色。如何创建和管理这些角色取决于授权过程的备份存储区。角色通过ClaimsPrincipal类上的IsInRole方法向开发人员公开。
我认为这个问题可以从数据库的角度来回答。 如果您注意到表是如何参与这个植入的,您将发现以下内容
AspNetUsers : each user has one row with all the attributes required by all users like email, address phone, password..... AspNetRoles ; defines different roles as per application requirements like GM , CTO, HRM,ADMIN, EMP. what each roles defines is as per application needs. AspNetUserRoles: each row links AspNetUsers and AspNetRoles and effectively links between one user and many roles. 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.
这个表的使用可以在用户/应用程序生命周期的某个时刻进行调整,以匹配特定的需求。
考虑到“采购经理”(PM)的早期阶段,我们可以有三种方法
Application populates AspNetUserRoles with one row to grants 'PM' right to buy. To issue purchasing order with any amount, user only need "PM" role. 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'. 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.
可以注意到,基于角色的是粗粒度的刚性权限,从系统管理的角度来看,这将简化应用程序用户的生活。然而,从业务需求的角度来看,这将限制用户的能力。 另一方面,基于索赔的是非常精细的权利,需要分配给每个用户。以索赔为基础会把业务推到极限,但会使系统管理非常复杂。
另一个可以考虑的选项是ABAC。
基于属性的访问控制采用了一种不同的方法,它根据每个用户的属性、他们请求的资源以及他们发出请求的环境向用户授予访问权。
ABAC的主要好处是可以对每个用户的权限进行细粒度控制。例如,使用ABAC,您可以为人力资源应用程序的用户授予仅为他们负责的区域导出人员报告的权限。因为模型被设计成可以扩展到任意数量的属性和权限,所以在ABAC中构建更动态的权限通常更容易。
这里的好文章总结了差异https://cerbos.dev/blog/the-hidden-costs-of-user-authorization
更广泛地说,您应该考虑基于属性的访问控制(ABAC)。RBAC和ABAC都是由美国国家标准与技术研究院(NIST)定义的概念。另一方面,CBAC是微软推出的一种模型,与ABAC非常相似。
点击此处阅读更多信息:
基于角色的访问控制NIST页面 基于属性的访问控制NIST页面