关于权限系统的一些思考
写在开始的话--好像叫前言吧
总算找到时间总结一下现在对于权限系统的思考了, 今天天气不错, 适合发白日梦和写博客. 既然是写在前面的话, 那么有几点是必须要说明的. 下面的想法可能会非常奇葩, 会给人一种生搬硬套 + 走投无路的感觉. 希望不小心看到的不要被这种想法折磨就好了. 然后, 这篇文章嘛, 其实很大的一部分是为了自己的思路做整理. 所以如果有时跳跃太犀利的话, 就当没看见吧~
方案1--字符串标识法:
原理: 用户 - 功能点.
理 & 论: 这个是比较简单, 但是给我的感觉又是最触及核心(我喜欢"触及核心"和"贴近本质"这两个词). 为什么这么说呢? 因为所谓权限, 从感性上来说就是一句话:(请用黑社会老大教训黑社会小弟的语气) 有些事情~你能干, 但是有些事情~~~你不能! 好吧, 那么简单来说呢, 所谓权限就是高中的一句英语句型: someone can do sth. 那么就是翻译成程序语言就是: 用户, 能做xx事情. 那么基于这句话的建模就是: 系统 == 功能点的集合. 在这上面, 我们不需要设计模式, 不需要模块化, 什么都不需要, 很纯, 很干净, 很傻, 很天真. 但是, 这是我觉得这里是最贴近本质的部分. 这里是赤子之心, 这里是返璞归真. 这里是起点, 这里是终点.
方法: 好吧, 其实这个也是被广泛用到的方法了. 首先这个理论是某人能做某事, 那么某事对于某人来说只有两种状态: 能做 / 不能做. 如果用数字来表示, 我推荐1 / 0, 当然不排除某些奇葩喜欢用2/3, 4/5. 好吧~ 如果事成了记得写篇论文(内心的奇葩一巴掌过来, miss). 然后我推荐用二进制表示, 比如第一个功能点是第一位, 第二个功能点是第二位, 如此类推, 在定义功能点的时候我们可以用 funcFlag = 1 << n. 来为每个功能点设标记. 然后配置用户权限的时候只需要把各个功能点的标识用 | , | 起来就好了(话说这个 | 应该叫异或). 然后每个用户都有一个二进制数, 然后这个二进制数就代表了这个用户具有哪些权限了.
拓展1: 好吧, 上面的方法目测是很美好, 实际上也很美好, 如果我的系统足够小(小于32个或64个功能点), 或者计算机硬/软件技术发展的足够犀利(intN,从硬件和软件的角度成立), 那么只用上面的技术配套完善的文档(主要是funFlag -- 功能描述), 其实是足够的了~ 那么如何解决int型存储的不足呢? 这个问题跟在学校的时候遇到的一个超大数相加的问题有点眉来眼去的感觉了~ 事实上还是有点区别的, 这里的解法(非标准, 是我的一个朋友给出的)是把二进制数压缩成16进制数, 然后用字符串存起来. 文档里面写明字符串的第n位包含哪些功能即可. 那么, 系统对于每个用户的权限都可以用一条字符串来描述了~(当然还有必不可少的文档啦~)
总结: 好了, 方法1其实是我比较钟爱的, 但由于数位问题, 他一般是在一些固定个数的配置项中用到--定义几个常量, 然后相 | 就解决问题了. 然后实际上会用到实际来解决权限问题的方法是拓展1提到的. 跟我提出这个想法的朋友说这个方法很复杂(?) 建议我不要用. 而我的看法是, 这个办法其实是很不错的. 说实现嘛, 其实只要是个智力正常, 不带坑的程序员, 是能实现的. 而这个方法最大的问题在于维护成本. 具体表现在, 配置一个用户权限的时候, 必须细化到每个功能点去配置. 代码维护的难度和可读性也不强(这点是我朋友提出的, 我对此是抱观望态度的~)
方案2--角色法:
原理: 用户 - 角色 - 功能点
理 & 论: 终于来到这个我一开始就想到的模型了(上面方案一是我在想:究竟能不能简单点啊?的时候想到的, 结果发现原来大家都想到了:( ). 这个模型就是把功能点纳入角色, 然后用户只要分配不同的角色就能拥有相应的功能点的(我自己敲出来都觉得啰嗦~). 这个理论相对简单(跟方法一比简直战斗力只有五啊~), 但是有几点是值得注意的, 比如: 我有一个用户属于整个群体的异类, 他拥有某些角色外的功能点, 这里有一个词比较好形容--特权(我就喜欢中华文化的博大精深). 对于这部分异类应该如何处理呢. 这是个谜. 因此这个原理要求用户是没有特权的 => 这样要求分工的边界需要非常明确(这个情况可能只会出现在理想乡~).
方法: 这里不玩字符串了, 直接上数据表. 权限表(pk: 权限ID), 用户表(pk: 用户ID), 角色表(pk: 角色ID), 角色-权限表(pk:角色ID + 权限ID), 用户-角色表(pk: 用户ID-角色ID). 总的来说是三张成员表和两张关系表. 也没什么技术含量了, 各个对号入座即可. 因为一个基于不靠谱理论产生的不靠谱方法(至少我这么认为), 因此我就不累赘了, 拓展吧.
拓展: 好的, 你以为这里会有什么高深的理论吗? 太天真了~ 在这个框架下如何解决特权问题呢? 这样的话只需要再建立一个特权的角色即可~ 什么? 你说万一有特权的角色很多导致间接性为每个用户都创建了一个特权的角色到头来还是走了方案一的路子? 如果我说这个模型其实只是一个简单的开模型(这个是我发明的词, 意思就是此模型只定义了你能干什么, 而没有定义你不能干什么~), 它并不能满足现实复杂的状况的话估计看到这里的人就会抽死我了吧. 抽死我吧!
总结: 这个模型其实并不复杂, 但是他对于特权问题不能很好的解决. 不过这个模型还是有其优点. 最大的优点就是实现起身非常简单, 起码符合大众逻辑. 使用它能满足大部分需求, 对于不能满足的需求, 它也能做到很好的让步和妥协. 缺点嘛~ 当然是有的, 例如每次用户操作的时候都必须访问一次数据库, 但是这个属于技术上问题, 可以通过技术解决. 比如本地读, 远端或者用一些持久化的框架也可以很好的解决这个问题. 但就整体而言, 这个模型还是非常适合大中小学生使用的.
方案3--逆向思维:
总结: 不要惊讶, 就是对上面两个方案的总结, 这样才能推理出我为什么能想到这一步. 首先, 针对方案一和方案二找共同点(他们两个模型你说有什么共同点呢?). 然后倒转这些共同点. 答案可能就在里面. 思考........................................好的, 也不知道想到没有, 或者说有没有想. 他们两个的共同点其实很明显, 就是都是基于用户作考虑的. 但是我们到底有没有考虑过功能点的心情呢? (啊~ 好像爱情肥皂剧). 因此为了解决特权问题, 我们需要重新考虑一下功能点的心情了~
原理: (用户 - 角色 - 功能点) + (功能点 - 用户)
理 & 论: 上面说了很多用户对应功能点了. 那么功能点对用户来说是怎样的呢? 其实谜底已经在黑帮大佬的那句话里面了~ 因为我们讨论的都是基于用户能做什么, 而没有规定用户不能做什么. 而通过角色来管理用户权限实际上是一种粗放式的解决方案. 而如何在这基础上细化(比如允许某用户能做一些角色外的事情, 或者不允许用户做一些角色内的事情), 这样就需要为每个功能点定义用户的访问权限了. 并且在这里定义的权限粒度更细, 权力更高(相对角色定义的权限而言).
方法: 在方案二方法里面的5张表的基础上再加一张 权限-用户表(pk: 权限ID + 用户ID), 变成三张成员表和三张关系表. 并且权限点-用户表里面定义的权限是覆盖角色-权限表, 这样一个比较符合实际情况的模型就出来了.
总结--并不完美的结局:
这里探讨了权限的模型, 基本依据嘛. 是没有的~ 但是作为一个用了win系统这么多年的人, 有想法是必然的. 方案一有人跟我说是Linux的权限设计就是这样~ 我也没有做过调查, 也不知道他所说的是哪个版本的权限设计, 但就这样吧, 毕竟这是一个很好的思路和切入点. 重点是, 对比三个方案, 我更喜欢方案一.
之所以说并不完美的结局, 是因为这个模型肯定并不是最好的, 最全的. 就我想到的很多地方也没有涉及讨论到~ 比如, 用户权限的继承性(比如A是B和C的一个上级那么A一般是继承了B和C的权限), 权限的等级划分(功能点的粒度), 角色管理的拓展(比如有组啊, Department啊的概念)等等等等.
不过正因如此, 正因为模型的不完美, 程序才会有bug, 而又正因为这些bug, 程序员才有饭食, 因此BUG是美好的, 不完美是赛高的~
-----GSSL -----
2014-03-18
后记--反思:
刚才基于上面的考虑, 去跟度娘交流了一下, 发现了一个名词叫"RBAC", 具体参阅下面的链接:
http://baike.baidu.com/link?url=ORrqMuCuxuSeiCFBDJNTPMb5pDZco1Lc9qFqMJrDFlf4QZlYRU89zXWZhkeqkkGF
而方案二我思考之后认为是这个模型的原型. 而方案三是一个变种, 度娘还告诉了我们其他的变种, 比如RBAC96模型, ARABC97模型, DRABC等. 其中涉及了授权认证(对赋予权限的一方进行分离), 角色分级, 等等的新的概念, 其实这里的目的也只不过是抛砖引玉. 因为权限系统是非常庞大的一项工程. 其中涉及的领域也是十分之多, 就我所见除了基础的码农之外(也就是程序猿啦), 会有信息安全领域, 计算机网络, 应用数学, 管理学等等的人参与才能实现和完善. 因此一人之力甚微, 遇到的问题肯定会很多. 而值得安慰的是: 就算别人家好几百人来做的这个系统, 到头来还是会遇到问题, 还是需要不断的Debug(而且他们遇到的问题肯定比小系统多, 因此需要更加多的人手, 然后产生更加多的问题, 然后....). 因此得出一个非常离题的结论是: 小系统养家糊口, 大系统养家s糊口s.
最后大家反映口语化比较严重, 其实嘛, 作为一个一天到晚也不怎么写公文老想着写小说的人来说, 也就这点水平了. 往后会注意注意, 大家见谅见谅~~
-----GSSL -----