RBAC新解:基于资源的权限管理(Resource-Based Access Control)

什么是角色
当说到程序的权限管理时,人们往往想到角色这一概念。角色是代表一系列可执行的操作或责任的实体,用于限定你在软件系统中能做什么、不能做什么。用户帐号往往与角色相关联,因此,一个用户在软件系统中能做什么取决于与之关联的各个角色。
例如,一个用户以关联了”管理员”角色的帐号登录系统,那这个用户就可以做项目管理员能做的所有事情哦,管理员可以做啥,整个用户就可以得到所有的权限。

基于角色的访问控制(Role-Based Access Control)
既然角色代表了可执行的操作这一概念,一个合乎逻辑的做法是在软件开发中使用角色来控制对软件功能和数据的访问。你可能已经猜到,这种权限控制方法就叫基于角色的访问控制(Role-Based Access Control),或简称为RBAC。
有两种正在实践中使用的RBAC访问控制方式:隐式(模糊)的方式和显示(明确)的方式。
今天依旧有大量的软件应用是使用隐式的访问控制方式。

隐式角色

即直接通过角色来验证用户有没有操作权限,如在应用中CTO、技术总监、开
发工程师可以使用打印机,假设某天不允许开发工程师使用打印机,此时需要从应用中删除相应代码;再如在应用中CTO、技术总监可以查看用户、查看权限;突然有一天不允许技术总监查看用户、查看权限了,需要在相关代码中把技术总监角色从判断逻辑中删除掉;即粒度是以角色为单位进行访问控制的粒度较粗;如果进行修改可能造成多处代码修改。

拿”项目管理员”来说,系统中并没有对”项目管理员”能进行什么样的操作进行明确定义,它仅是一个字符串名词。开发人员通常将这个名词写在程序里以进行访问控制。例如,判断一个用户是否能查看项目报表,程序员可能会编码如下:

 隐式地基于角色的权限控制:
if (user.hasRole("Project Manager") ) {
    //show the project report button
} else {
    //don't show the button
}

在上面的示例代表中,开发人员判断用户是否有”项目管理员”角色来决定是否显示查看项目报表按钮。请注意上面的代码,它并没有明确语句来定义”项目管理员”这一角色到底包含哪些可执行的行为,它只是假设一个关联了项目管理员角色的用户可查看项目报表,而开发人员也是基于这一假设来写 if/else 语句。

脆弱的权限策略
上面的权限访问控制是非常脆弱的,非常的不具有可扩展性,相当于写死了。。。。一个极小的权限方面的需求的变动都可能导致上面的代码需要重新修改。假如我说我们需要一个’部门管理员’角色,他们也可以查看项目报表。又需要再次修改代码?整个多麻烦啊!到处都是整个怎么改变呢

修改过的隐式的基于角色的权限控制:
if (user.hasRole("Project Manager") || user.hasRole("Department Manager") ) {
    //show the project report button
} else {
    //don't show the button
}

如果需求方要求动态地创建、删除角色以便他们自己配置角色,又该如何应对呢?
像上面的情况,这种隐式的(静态字符串)形式的基于角色的访问控制方式难以满足需求。理想的情况是如果权限需求变动不需要修改任何代码。怎样才能做到这一点呢?

显式地访问控制:Good更加具有可扩展性

上面的例子我们看到,当权限需求发生变动时,隐式的权限访问控制方式会给程序开发带来沉重的负担。在权限需求发生变化时不需要去修改代码就能动态的满足需求。理解的情况是,即使是正在运行的系统,你也可以修改权限策略却又不影响最终用户的使用。当你发现某些错误的或危险的安全策略时,你可以迅速地修改策略配置,同时你的系统还能正常使用,而不需要重构代码重新部署系统总结就是不需要修改代码,不需要停止服务器
怎样才能达到上面的理想效果呢?
思考一下,上面的例子这些代码最终的目的,想一下它们最终是要做什么样的控制?
从根本上说,这些代码最终是在保护资源(项目报表),是要界定一个用户能对这些资源进行什么样的操作(查看/修改)。当我们将权限访问控制分解到这种最原始的层次
在程序中通过权限控制谁能访问某个资源,角色聚合一组权限集合这样假设哪个角色不能访问某个资源,只需要从角色代表的权限集合中移除即可;无须修改多处代码;即粒度是以资源/实例为单位的;粒度较细。 角色对应了资源的访问哦,只要把明确的资源定义下面,这样就是一个资源操作的集合哦,把资源给某个角色就好了,这样这个角色就拥有了访问的权限了。
我们可以修改上面的代码块,以基于资源的语义来更有效地进行权限访问控制:

if (user.isPermitted("projectReport:view:12345")) {
    //show the project report button
} else {
    //don't show the button
}

上面的例子中,我们可明确地看到我们是在控制什么。上面的语句明确地表示了“如果当前用户允许查看编号为12345的项目报表,则显示项目报表按钮”。查看12345整个项目报表是一个资源哦,需要分配个某个角色,配置个某个用户就好了。这里的资源都是最小的粒度啦,不能再往下面划分了哦,如果要定义更多的细粒度的代码就需要进行修改代码啦,这个动态的修改就是不行啦,这个就是笔者的理解。你还可以比如 查找,删除等等权限这些都是细腻度哦CRUD各种权限。

RBAC新解:Resource-Based Access Control

这种显式的机制带给我们的富有弹性的权限模型。
如果你仍想保留或模拟传统的基于角色的权限访问控制,你可以将权限(可执行的操作)直接分配给某个角色。这种情况下,你依旧是在使用基于角色的权限访问控制方式(不同之处在于你需要明确地界定角色中的权限,而不是传统的使用角色字符串隐式地进行权限控制)。
但在这种新的模型下,已不必再局限于角色了。你可以将权限直接分配给用户、组或其它你觉得可以的对象。因为上面显式地、基于资源的权限访问控制的诸多好处,或许可以给RBAC一个新的定义:“Resource-Based Access Control”。

Apache Shiro

如果你好奇现实世界有没有被多个系统使用的基于资源的权限控制框架,Apache Shiro。它是一个java平台的现代权限管理框架。通过它的权限(Permission)概念,Shiro很好地支持基于资源的权限访问控制。这个也是笔者学习Shiro的意义哦!

其实笔者之前就知道了基于角色的权限访问控制,还是比较的不错哦,只不过是笔者自己理解错了,理解成了资源的这种类型了,角色可以随便创建,细腻度的东西写死的,那个就是资源可以分配给角色,其实吧,这个就是基于资源的权限访问控制啦。

笔者上次在杭州某公司面试的时候,被一个比笔者还有年轻的面试官问了一个问题,如何进行权限控制,笔者也没有专门的去研究过这个东西,就是知道比较的复杂,仅仅知道一个用户给予一个角色,一个角色分配某些资源,这种资源这样定义比如CRUD等等,在界面上显示的按钮等信息哦,都是资源的。居然瞎猜对了,哈哈。小小的面试官说,今天就我说的勉强对哈,其实我也是不是很清楚怎么去实现的,所以就来了解Shiro,除了这个之外想了解大神写的代码整体的设计构架比较的有扩展性,设计模式导出可见,非常的高明,易扩展,这样的学习值得我们这中刚刚毕业的初级码农好好的去学习一下子,更利于我们整体性的提高,笔者之前也是去看过设计模式子类书,还是觉得理解不够深刻,还是比较的浅薄,实际的项目中这样的设计更容易理解,不过你自己的想想,让你来写的话是怎么的一个样子呢?

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值