大话权限设计

前言

      如何实现一个高效简单的系统权限体系是我们长期以来都在思考的问题,也是最近一年来我思考得最多的问题,我们所期望的权限都是应当能够根据应用的需要不断添加和扩展的权限,并且最好能够以最简单的方式来支持,那就最好不过了。

   内容

  • 什么是权限系统
  • 一个简单的设计 
  • 基于角色的访问
  • 最初的数据权限
  • 更好的解决方法 
  • 最近的战役
  • 总结

 

什么是权限系统

     那么我们需要一个什么样的权限系统呢或者说什么是权限,我查看了很多的相关资料想要试图解决这个问题,最后看一个最简单最明确的答案"安全问题就是解决谁对什么能够进行什么控制的问题”。如何来分析这段话呢,我敢保证这是我见过的最明确也是最抽象的需求,通过什么样的方式来分析和解决这个需求问题呢。

而对复杂的问题我们必须拿出强大武器才行啊,对于不明确的概念我们首先需要完成的是将“概念明确化”先将这段话中不明确的代词进行明确化,那么我们就从第一个代词开始“”是指什么呢,“员工”,“用户”,“领导”,...,还是什么其它呢,我想对于不同的问题我想需要采用不同的概念,如果这个系统只是用于解决公司内容的相关问题,那么这里使用“员工”最好不过,如果专门用于解决“领导”的个人问题,那么“领导”也不错。这里主要需要考虑我们所面临问题和抽象的层次,同时还需考虑到具体应用的行业标准。对于需要大多数情况采用“用户”或“当前用户”是一个比较好抽象,我们这里采用“当前用户”,这样比“用户”更明确一些,那么这段需求就变成了“安全问题就是解决当前用户对什么能够进行什么控制的问题”。

好解决了第一个抽象之后,对于其它问题我们同样采用相关的方式来进行分析,“当前用户对什么” 之中的“什么”当前相关问题的抽象层次之中基本上都是采用“安全资源对象”来进行抽象的,当然也可以根据实际处理的问题进行抽象,我们这里主要是考虑通用性。而对于“能够进行什么访问”之中的“什么”这里也需要根据相关问题的来进行设定,这里我们采用“访问或拒绝”,那么这一段需求就变成“安全问题就是解决当前用户能够对资源对象进行访问或拒绝控制的问题”,如果实现需要就是对功能进行控制还可以说成是“安全问题就是解决当前用户能够对功能进行访问或拒绝控制的问题"。

 

一个简单的设计

了解了问题的本质后,我们需要做的就是要完成它,那么怎样来完成这呢。首先我们需要从需求之中将我们领域模型分离出来: 

 

如果是一个简单的权限设计,那么整个权限系统不这样就完成了,非常的简单明了(对于这里各对象所需要领域访问就不在说明)。

 

基于角色的访问

当简单的设计使用的用户数量一天一天的增加的时候,我们发现给一个一个用户分别进行权限的设置是一件非常困难的工作。好,看来是我们修改设计的时候到了。最先想到的是我们必须对用户进行分组,将对用户的访问授权设置到这些组之中。好,那我们就设置一个用户组,通过用户组来设置吧,但我们又会想到在实际的业务之中一个多岗的情况很多啊,那么怎么办呢,同时如果能够以现实际之中公司的实际情况设置权限最好不过,因为这样对于系统的管理人员来说,只需要了解公司内部的情况就可以了,那么怎么样来协调这两个问题呢。

其实这个问题在安全设计的前辈们早已想到应对之策,就是将这些对象抽象以“角色”来表示这些抽象的概念。那么加入的角色对于我们的领域模型带来了什么样的变化呢?

这样对于我们的管理来说真的大大的简化了啊,但这就完全的满足了我们的条件了吗?

 

最初的数据权限

当我们正在为自己的设计而高兴的时候新的问题又来了,怎么回事呢。小郑啊,北美销售部只能够管理北美的销售啊,发动机事业部只能够销售发动机产品啊,你那个程序是怎么回事啊,怎么都能够看啊,还有怎么部长都能够审批100W以上的定单啊。

啊,我快要完蛋了。

好,兵来将挡,水来土淹什么问题都能不倒我。

看来我们还必须要设计满足数据权限的要求才行啊。

好吧,那我怎么样子来实现呢...?好吧,我应在安全资源之中加一个数据规格,在访问控制之中加入一个值的设定,怎么样,这下行了吧?

 

好吧,现在就看我来实现它吧,以我精湛的技术。

啊,什么,一个用户多个角色,不同的角色有不同的数据规则控制。啊,还需要数据控制的合并,没事我们使用提供者模式来解决,实现不同的合并提供者,使用提供者来合并结果。

啊,什么,怎么样转换到数据访问的控制,没事,咱们硬编码。

啊,不可能吧,连个获取操作都需要进行控制啊。

啊,我不行了。倒在了黎民前了晚上。

 

更好的解决方法

如果没有能够对数据权限进行详细的分析,那么一定会在倒在黎明的前夜,没有完整的解决方法,那是不行的。好,我们先来分析一个数据权限的要求,这里我只能够写出我对于这部分的分析,数据权限的限制总是:{实体属性值 条件 允许值}这三个产品分组成,如:数据规则,销售部长只能够审核销售金额小于100W的定单这里的三者是{销售定单.合计金额 小于 100W}, 销售员小张只能够销售摩托车产品,这其中的三者是{销售项目.产品类型 属于 摩托车)

所以这里对于数据的限制都只包括三个要素:领域实体属性 条件 允许值。这三者的结合就限制的约束。那么这三都之中都有哪些情况呢?

领域实体属性:这个基本上都没有什么变化。

条件:如果是条件就只有那么几种,有大于,小于,等于,实体范围等等。

允许值:允许值这里经过我的分析包括三种情况{设置值,用户属性相关值,业务设定值}

这三种情况分别使用于以下情况:设置值表示是我们是设置权限的时候直接进行设置的如100W,用户属性相关值表示与用户的某一个属性相关,如:部门,职务等。还有一种就是业务相关的情况,这类情况相当于是在业务之中设置数据。这类问题在SAP之中设置比较多,感兴趣的可以去了解一下SAP之中的相关设置。

在这里对于条件的设置基本上都只有固定的几种,可以采用枚举的方式来进行,而对于充许值这一个点,因为不同的业务所需要的不同的数据和相关内容不想同,因此,将这一个允许值的获取设置为一个相关的接口来进行,而在进行配置的时候只设置一个相关值,由接口去解晰和获取。这时候的领域模型图如下:

 

 

最后的战役  

在解决了领域问题之后,我们还需要考虑提供什么方式来获取这些服务,这里首先需要考虑使用权限的两种情况,一种是当需要显示相关界面时; 二是当需要执行相关操作时。

  • 第一种情况:当我们进入到提供定单的界面,那么显示出来的相关产品肯定是我们能够允许提供的产品,显示出来的国家也是我们能够进行销售的国家。
  • 第二种情况:当我们提交定单时,提供的内容必须进行检查。

对于第一种情况:我们在执行GetCountries()和GetProducts()这两个方式的内部就必须执行条件的限制,那么如何来实现这个条件的限制呢。这里必须要通过一种方式让GetCountries了解到当前正自于那一个安全的环境之中,再获取获取相应的数据限制,查看这个限制的实体是否为Country如果是那么是那个条件进行的设置编号,国家名称,上级部门。再将这些条件转换为对应的SQL来进行限制,如果这些方法都是通过硬编号来完成,那么一定是一个复杂的工作,好在现在的ORM工具直接就支持领域实体,属性,条件等内容,直接可以将这些配置的安全值设置到这些访问之上,这样就可以完成整个数据限制,同时还需要考虑到如果是在多个不同的应用之间设置这些服务,还需要考虑到安全的层次关系,在多个层次之中使用和设置多层安全环境。这就必须使用一个对应的环境管理类来管理这些环境。对于这个环境可以采用SecurityContext来表示,而对于这个环境的管理类使用SecrityContextManager的线程单例模式来进行设置。在实现的过程之中,如果需要一个新的安全环境则建立一个新的SecurityContext,在新实例的SecurityContext之中将自己注册到SecurityContextManager的单实例之中。同时在建立SecurityContext时传入相关的安全资源对象,对这些对象进行安全检查,如果没有进行授权则引发System.Security.SecurityException对象。

在开发数据访问层时,通过SecurityContextManager.Instance来获取如:Employee实体的的限制,通过前面所设计的获取允许值提供者接口来获取允许的值,并且将属性,条件,允许值,转换为对应的SQL来进行调用。这样就实现了多层次的数据权限。如果对应的ORM工具能够直接支持条件的设置则可以将这个工作直接编写对应的转换器来进行转换,这样可以大大的提高开发的效率,并且还可以根据需要对领域成员进行新的数据约束,而不必修改应用程序。

同时如果所需要限制的数据资源不是领域实体中的数据,也可以通过这种方式来设置自己的数据范围的检查。

 

总结

本文主要是介绍一种安全的实现方式,安全不是一个简单到只需要在某一具体层就能够解决的问题,而需要在多个层次进行多层次的设置。形成类似于IIS式的多层次,多角度权限设置,这里只是给出了其中最为核心的内容,没有给出具体的代码,这主要是因为不能够公布公司内部开发的程序,所以可能对于完整的理解有所不足。

 

对本文有什么好的意见或见意请大家多指教。

 

 

 

posted on 2008-12-23 11:05 蓝色游骑兵 阅读(4534) 评论(18) 编辑 收藏

评论

#1楼  回复 引用   

解释的不错,正在做一个内部的应用系统,在做类似的权限系统,系统需要解决当前用户能做什么,当前用户在系统中能知道什么内容.做完后,准备把系统放出来.
2008-12-23 11:14 | aabc[未注册用户]

#2楼  回复 引用 查看   

前一段时间,我也开发了一个,LZ是否考虑了一个大的权限,可能里面有几个小权限的情况?比如说,用户管理权限,它包括了用户查询、用户增加等, 某个用户可能只有小权限的一部分。

另外,如果把权限授予功能考虑进去就完美了,比如说,现在用户1有10个权限,他可以自己安排给底下的人用其中的5个,用完可以收回来!
2008-12-23 11:35 | 火之光      

#3楼  回复 引用 查看   

慢慢研究
2008-12-23 11:37 | cloudgamer      

#4楼  回复 引用 查看   

记得单片机中有一种方式,使用二进制的各个位来进行访问或拒绝的控制。如果能用在系统的权限设计中,应该是比较简洁的。比如:用0x1111(F)表示允许增加、删除、查询、修改,0x1010(A)表示允许增加、查询,不允许删除、修改。如果用户对不同的Resource(R1,R2),其权限(Control)可以用(C1,C2)表示,因为是十六进制为(0-F)的单个字符,再简化一下,用(C1C2)表示,所以对于N个Resources其权限就可以简化为(C1C2C3....Cn)的一个字符串。可以直接存在User表中,或是Role表中。
2008-12-23 12:19 | csuman      

#5楼  回复 引用 查看   

--引用--------------------------------------------------
csuman: 记得单片机中有一种方式,使用二进制的各个位来进行访问或拒绝的控制。如果能用在系统的权限设计中,应该是比较简洁的。比如:用0x1111(F)表示允许增加、删除、查询、修改,0x1010(A)表示允许增加、查询,不允许删除、修改。如果用户对不同的Resource(R1,R2),其权限(Control)可以用(C1,C2)表示,因为是十六进制为(0-F)的单个字符,再简化一下,用(C1C2)表示,所以对于N个Resources其权限就可以简化为(C1C2C3....Cn)的一个字符串。可以直接存在User表中,或是Role表中。
--------------------------------------------------------
一个数值的位有限,不易扩充,如果不考虑通用性,这样设计当然可以。但是不同应用环境,权限的数目有可能很多,也有可能很少,就样就很难应用位来设计了,因为你无法预知究竟会有多个种权限。
2008-12-23 13:07 | 麦舒      

#6楼  回复 引用   

为什么每个人都来谈通用权限,又有哪一位能能用呢?
2008-12-23 13:11 | jelyly[未注册用户]

#7楼  回复 引用 查看   

大话:
1、 戏说;说谎的意思
2、虚夸不实的话。

  唐 李商隐 《杂纂》:“穷汉说大话。” 明 李贽 《豫约》:“故我尝自谓我能为忠臣者,以此能忘家忘身之人卜之也,非欺诞说大话也。” 清 李渔 《奈何天·狡脱》:“我笑你难争气,泼天大话才离嘴,代伊惭愧,代伊惭愧。” 茅盾 《子夜》十四:“ 屠维岳 的法宝就是说大话,象煞有介事,满嘴的有办法,

:)
2008-12-23 13:30 | James-yu      

#8楼  回复 引用 查看   

楼上有意思,
文章不错,感觉很面熟。
2008-12-23 14:33 | 齐.net      

#9楼  回复 引用 查看   

快断网了,赶紧mark一下,回来看!
2008-12-23 14:37 | Selfocus      

#10楼  回复 引用 查看   

我感觉 应该把这些权限分类.按不同的去解决,如:你有某个操作功能的权限,包括读写打印等 按方案1 2 就应该可以了...如果要有订单金额>100W之类的权限 我感觉 是不是一般可以和工程流之类的配合起来解决.因为这一类的东西我感觉和权限的关系比较少些 而和业务逻辑的关系比较多些 包括 某个部门有某些产品的权限.这些东西是业务的范围 应该用一个业务权限的方式来解决 我的系统中名称是:系统权限和业务权限.
系统权限相对比较简单
业务权限和工作流结合 而且 也有很大的变动性.
2008-12-23 20:48 | 方子      

#11楼  回复 引用 查看   

我现在的做法是,建立一个权限大类,一个权限子类,一个权限明细表,和一个ROLE角色表. 把所有的权限细化,或者定制性权限,然后用户登陆时把他的权限缓存一下,进行业务操作时进行时根据 业务相应的权限Id与缓存里的权限进行比较.
2008-12-24 14:54 | adpost      

#12楼  回复 引用   

一直没有很直接的概念,在资源这一部分的权限是如何细化的.看了您的文章,却明了了不少,以此谢过.并祝圣诞节快乐!
2008-12-25 09:25 | abcd[未注册用户]

#13楼  回复 引用 查看   

@James-yu
无聊的人啊..

@蓝色游骑兵
讲得不错...
2009-02-16 15:28 | Gary Gong      

#14楼  回复 引用 查看   

@方子
工作流的活动性是流程走向,而这里是权限控制,类似,但不同,不过如果是用户自定义工作流,且强大到可以根据某个字段定走向,且走向绑定权限,那么两者也可殊途同归.
2009-02-16 15:31 | Gary Gong      

#15楼  回复 引用 查看   

文章写的好极了,文字思路都好诶,谢谢博主分享,希望能多看到这样的好文!
2009-05-21 21:58 | Neil_Huang      

#16楼  回复 引用   

这是我目前见过的,关于权限系统分析写得最好的。
Mark!!!
2009-05-23 23:02 | seven.dev

#17楼  回复 引用 查看   

文章是不错, 但我还是想说: 文笔实在很一般, 错别字一堆, 而且语句不通顺, 看起来挺累的...个人评价. ^_^
2010-04-12 09:28 | Binary Cooker      

#18楼  回复 引用 查看   

不错不错
2011-12-22 10:37 | tianci.free      

导航

<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

公告

其中主要记录我对于一些问题的思考过程,最后选择的结果.

昵称:蓝色游骑兵
园龄:4年1个月
粉丝:2
关注:0

搜索

 
 

常用链接

我的标签

随笔档案

文章分类

最新评论

阅读排行榜

评论排行榜

推荐排行榜