在系统中发生的事情,抽象的说都是某个主体(subject)在某个资源(resource)上执行了某个操作(operation)。
subject --operation]--resource
所谓权限管理,就是在这条信息传递路径中加上一些限制性控制。
主体试图去做的 limited by 系统允许主体去做的 = 主体实际做的。
可以看到,权限控制基本对应于filter模式。subject试图去做的事情应该由业务逻辑决定,因而应该编码在业务系统中。
先考虑最粗粒度的控制策略,控制点加在subject处,即无论从事何种操作,针对何种资源,我们首先需要确认subject是受控的。只有通过认证的用户才能使用系统功能,这就是authentication。boolean isallowed subject)
稍微复杂一些,控制可以施加在subject和operation的边界处(此时并不知道具体进行何种操作),称为模块访问控制,即只有某些用户才能访问特定模块。isallowed(subject, operation set)
第**控制直接施加在operation上,即操作访问控制。operation知道resource和subject(但它尚没有关于resource的细节知识),我们能够采取的权限机制是bool isallowed(subject, operation, resource), 返回true允许操作,返回false则不允许操作。
最简单的情况下,subject与resource之间的访问控制关系是静态的,可以直接写成一个权限控制矩阵。
for operationa:
resourcea resourceb
subjecta 1 0
subjectb 0 1
isallowed(subjecta, resourcea)恒等于true
如果多个operation的权限控制都可以通过这种方式来表示,则多个权限控制矩阵可以叠加在一起。
for operationa, operationb:
resourcea resourceb
subjecta 10 01
subjectb 01 11
当subject和resource的种类很多时,权限控制矩阵急剧膨胀,它的条目数是n*m。很显然,我们需要进行矩阵分解。这也是最基本的控制手段之一:
在系统中增加一个瓶颈,或者说寻找到隐含的结构。
subject_resource = subject_role * role_resource
这样系统权限配置条目的数量为 n*r + r*m, 如果r的数目远小于subject和resource,则实现简化。这称为rbac(role based access control),它的一个额外好处是权限系统的部分描述可以独立于subject存在,即在系统中没有任何用户的时候,通过角色仍然可以表达部分权限信息。可以说角色是subject在权限系统中的**(分解)。
有时候引入一个瓶颈还不过瘾,有人引入组的概念,与role串联,subject_resource = subject_group_role * role_resource
或着group与role并联,subject_resource = subject_group * group_resource
与role稍有不同,一般情况下group的业务含义更加明显,可能对应于组织结构等。将组织机构明确引入权限体系,有的时候比较方便,但对于权限系统自身的稳定性而言,未见得有什么太大的好处。并联模式有些多余,串联模式又过于复杂,细节调整困难,特别是多条控制路径造成的冲突情况。
一般情况下,我不提倡将group引入权限控制中。
比操作控制更加深入的控制就是数据控制了,此时需要对于resource的比较全面的知识。虽然表面上,仍然是。
boolean isallowed(subject, operation, resource),但控制函数需要知道resource的细节。例如行级控制(row-level)或者列级控制(column-level)的实现。因为我们一般情况下不可能将每一个条目都建模为独立的resource,而只能是存在一个整体描述,例如所有密级为绝密的文档。
在witrix平台中,数据控制主要通过数据源的filter来实现,因为查询条件(数据的定位条件)已经被对象化为query类,所以我们可以在合适的地方自由的追加权限控制条件。
以上的讨论中,权限控制都是根据某些静态描述信息来进行的,但现实世界是多变的。最简单的,当subject从事不同业务时,对应于同一组资源,也可能对应的权限控制并不同(在witrix平台中,对应于idatasource的模式切换)。更复杂一些, 在不同的时刻, 我们需要根据其他附加信息来作出是否允许操作的判断, 即此时我们权限设置的不仅仅是一些静态的描述信息, 而是一个完整的控制函数, 这就是所谓的工作流权限控制,一种动态权限控制。
权限系统(2)--operation
权限控制可以看作一个filter模式的应用, 这也符合aop思想的应用条件。在一个简化的图象中,我们只需要将一个判别函数 isallowed(subject, operation, resource)插入到所有安全敏感的函数调用之前就可以了。虽然概念上很完美,具体实现的时候仍然有一些细节上的问题。
基本的困难在于很难在最细的粒度上指定权限控制规则(连续的?动态的?可扩展的?
),因而我们只能在一些关键处指定权限规则,或者设置一些整体性的权限策略,然后通过特定的推理来推导出细粒度的权限规则,这就引出结构的问题。我们需要能够对权限控制策略进行有效的描述(控制策略的结构),并且决定如何与程序结构相结合。subject, operation和resource为了支持推理,都可能需要分化出复杂的结构,而不再是简单的原子性的概念。
而在与程序结构结合这一方面,虽然aop使得我们可以扩展任何函数,但这种扩展需要依赖于cutpoint处所能得到的信息,因而权限控制的有效实施也非常依赖于功能函数本身良好的设计。有的时候因为需要对结构有过于明确的假定,权限控制的实现不得不牺牲一定的通用性。
下面我们将分别讨论一下operation, subject和resource的结构分解的问题。首先是operation。
说到推理结构,让人最先想起的就是决策树,树形结构,在面向对象语言中可以对应于继承。金字塔式的树形结构也正是在现实世界中我们应用最多的控制结构。通过层层分解,operation的结构可以组织为一棵树,应用程序 ==各个子系统 ==每个子系统的功能模块 ==子功能模块
=> 每个模块的功能点(具有明确的业务含义) =每个功能点对应的访问函数(程序实现中的结构)
一个常见的需求是根据权限配置决定系统菜单树的显示,一般控制用户只能看到自己有权操作的功能模块和功能按钮。这种需求的解决方法是非常直接的。首先,在后台建立子系统到功能模块,功能模块到功能点以及功能点到实现函数之间的映射表(如果程序组织具有严格规范,这甚至可以通过自动搜集得到)。
然后,在权限配置时建立用户与功能点之间的关联。此时,通过一个视图,我们就可以搜集到用户对哪些功能模块具有访问权限的信息。
为了控制菜单树的显示,witrix平台中的sitemap采用如下策略:
1. 如果用户对某个子功能具有操作权限,则所有父菜单项都缺省可用。
2. 如果用户对某个功能具有操作权限,并且标记为cascade,则所有子菜单项都自动缺省可用。
3. 如果明确指定功能不可用,则该菜单及子菜单都强制不可用。
4. 如果明确指定功能对所有人可用,则不验证权限,所有子菜单自动缺省可用。
4. 强制设定覆盖缺省值。
5. 不可用的菜单缺省不可见。
6. 明确标记为可见的菜单即使不可用也可见。
7. 父菜单可见子菜单才可见。
我们通过预计算来综合考虑这些相互影响的控制策略。尽量将推导运算预先完成也是解决性能问题的不二法门。
在witrix平台中,每一次网络访问的url都符合jsplet框架所要求的对象调用格式,需要指定objectname和objectevent参数,这就对应于功能点的访问函数。访问控制点集中在objectmanager并且访问格式是标准的。使用spring等aop方式实现细粒度访问控制,困难似乎在于不容易引入外部配置信息(例如功能点信息等),而且控制点所对应的对象函数格式也不统一,因而多数需要在细粒度上一一指定。
权限系统(3)--subject
权限控制中,subject可能不会简单的对应于userid, 而是包含一系列的security token或certificate, 例如用户登陆地址,登陆时间等。一般情况下,这些信息在权限系统中的使用都是很直接的,不会造成什么问题。
subject域中最重要的结构是user和role的分离,可以在不存在user的情况下,为role指定权限。有人进一步定义了usergroup的概念,可以为usergroup指定role,而user从其所属的group继承role的设置。一般情况下,我不提倡在权限系统中引入usergroup的概念。
这其中最重要的原因就是它会造成多条权限信息传递途径,从而产生一种路径依赖, 并可能出现信息冲突的情况。一般user与group的关联具有明确的业务含义,因而不能随意取消。如果我们希望对user拥有的权限进行细调,除去user从group继承的某个不应该拥有的权限,解决的方法很有可能是所谓的负权限,即某个权限条目描述的是不能做某某事。
负权限会造成各个权限设置之间的互相影响,造成必须尝试所有权限规则才能作出判断的困境,引出对额外的消歧策略的需求,这些都极大的限制了系统的可扩展性。在允许负权限的环境中,管理员将无法直接断定某个权限设置的最终影响,他必须在头脑中完成所有的权限运算之后才能理解某用户最终拥有的实际权限,如果发现权限设置冲突,管理员可能需要多次尝试才能找到合适方案。这种配置时的推理需求可能会增加配置管理的难度,造成微妙的安全漏洞,而且负权限导致的全局关联也降低了权限系统的稳定性。
我更倾向于将group作为权限设置时的一种辅助标记手段,系统中只记录用户最终拥有的角色,即相当于记录用户通过group拥有权限的推导完成的结果, 如果需要权限细调,我们直接在用户拥有的角色列表上直接进行。当然,如果实现的复杂一些,权限系统对外暴露的接口仍然可以模拟为能够指定usergroup的权限。
Android系统架构基本模式解析
如今,大家面对市场中种类繁多的手机必然挑的眼花缭乱。不过,在智能手机占据主要地位的今天,挑选手机的主要因素就是挑选一款性能高的手机操作系统,android就是其中的一个必然选择。android系统架构和其操作系统一样,采用了分层的架构。android分为四个层,从高层到低层分别是应用程序层 应用程序...
Android系统架构基本模式解析
android系统架构之应用程序。android会同一系列核心应用程序包一起发布,该应用程序包包括email客户端,sms短消息程序,日历,地图,浏览器,联系人管理程序等。所有的应用程序都是使用j a语言编写的。android系统架构之应用程序框架。开发人员也可以完全访问核心应用程序所使用的api框...
作文基本模式
作文模式 十句作文法 第1 段 引言段 s 1 引出主题,即引出本文要讨论的问题,如宠物问题,体育问题,大学生打工问题等。s 2 确立论点,即表明作者对这个问题的基本看法,比如是赞成还是反对等。第2 段 正文段 s 3 承上启下,重复上一句的论点,提纲挈领本段要讨论的几个论据。s 4 第一论据 引出...