﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-DreamAngel-随笔分类-软件设计</title><link>http://www.blogjava.net/DreamAngel/category/37428.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 15 Feb 2009 18:57:54 GMT</lastBuildDate><pubDate>Sun, 15 Feb 2009 18:57:54 GMT</pubDate><ttl>60</ttl><item><title>OA系统权限管理设计方案</title><link>http://www.blogjava.net/DreamAngel/archive/2009/02/14/254641.html</link><dc:creator>飞翔天使</dc:creator><author>飞翔天使</author><pubDate>Sat, 14 Feb 2009 02:18:00 GMT</pubDate><guid>http://www.blogjava.net/DreamAngel/archive/2009/02/14/254641.html</guid><wfw:comment>http://www.blogjava.net/DreamAngel/comments/254641.html</wfw:comment><comments>http://www.blogjava.net/DreamAngel/archive/2009/02/14/254641.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/DreamAngel/comments/commentRss/254641.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/DreamAngel/services/trackbacks/254641.html</trackback:ping><description><![CDATA[<p>l 不同职责的人员，对于系统操作的权限应该是不同的。优秀的业务系统，这是最基本的功能。
<p>l 可以对&#8220;组&#8221;进行权限分配。对于一个大企业的业务系统来说，如果要求管理员为其下员工逐一分配系统操作权限的话，是件耗时且不够方便的事情。所以，系统中就提出了对&#8220;组&#8221;进行操作的概念，将权限一致的人员编入同一组，然后对该组进行权限分配。
<p>l 权限管理系统应该是可扩展的。它应该可以加入到任何带有权限管理功能的系统中。就像是组件一样的可以被不断的重用，而不是每开发一套管理系统，就要针对权限管理部分进行重新开发。
<p>l 满足业务系统中的功能权限。传统业务系统中，存在着两种权限管理，其一是功能权限的管理，而另外一种则是资源权限的管理，在不同系统之间，功能权限是可以重用的，而资源权限则不能。</p>
<p>&nbsp;</p>
<p>针对OA系统的特点，权限说明：
<p><strong>权限</strong>
<p>在系统中，权限通过<strong>模块</strong><strong>+</strong><strong>动作</strong>来产生，模块就是整个系统中的一个子模块，可能对应一个菜单，动作也就是整个模块中（在B/S系统中也就是一个页面的所有操作，比如&#8220;浏览、添加、修改、删除&#8221;等）。将模块与之组合可以产生此模块下的所有权限。
<p><strong>权限组</strong>
<p>为了更方便的权限的管理，另将一个模块下的所有权限组合一起，组成一个&#8220;<strong>权限组</strong>&#8221;，也就是一个模块管理权限，包括所有基本权限操作。比如一个权限组（用户管理），包括用户的浏览、添加、删除、修改、审核等操作权限，一个权限组也是一个权限。
<p><strong>角色</strong>
<p>权限的集合，角色与角色之间属于平级关系，可以将基本权限或权限组添加到一个角色中，用于方便权限的分配。
<p><strong>用户组</strong>
<p>将某一类型的人、具有相同特征人组合一起的集合体。通过对组授予权限（角色），快速使一类人具有相同的权限，来简化对用户授予权限的繁琐性、耗时性。用户组的划分，可以按<strong>职位、项目</strong>或其它来实现。用户可以属于某一个组或多个组。
<p>通过给某个人赋予权限，有4种方式(参考飞思办公系统)
<p>A. <strong>通过职位</strong>
<p>a) 在职位中，职位成员的权限<strong>继承</strong>当前所在职位的权限，对于下级职位拥有的权限不可继承。
<p>b) <strong>实例中</strong>：如前台这个职位，对于考勤查询有权限，则可以通过对前台这个职位设置考勤查询的浏览权，使他们有使用这个对象的权限，然后再设置个，考勤查询权（当然也可以不设置，默认能进此模块的就能查询），则所有前台人员都拥有考勤查询的权利。
<p><strong>B. </strong><strong>通过项目</strong>
<p>a) 在项目中，项目成员的权限来自于所在项目的权限，他们同样不能继承下级项目的权限，而对于项目组长，他对项目有全权，对下级项目也一样。
<p>b) <strong>实例中</strong>：在项目中，项目成员可以对项目中上传文档，查看本项目的文档,可以通过对项目设置一个对于本项目的浏览权来实现进口，这样每个成员能访问这个项目了，再加上项目文档的上传权和查看文档权即可。
<p>c) 对于组长，因为可以赋予组长一个组长权（组长权是个特殊的权限，它包含其他各种权限的一个权限包），所有组长对于本项目有全权，则项目组长可以对于项目文档查看，审批，删除，恢复等，这些权限对于本项目的下级项目依然有效。
<p><strong>C. </strong><strong>通过角色</strong>
<p>a) 角色中的成员继承角色的权限，角色与角色没有上下级关系，他们是平行的。通过角色赋予权限，是指没办法按职位或项目的分类来赋予权限的另一种方式，如：系统管理员，资料备份员&#8230;
<p>b) <strong>实例中</strong>：对于本系统中，全体人员应该默认都有的模块，如我的邮件，我的文档，我的日志，我的考勤&#8230;&#8230;，这些模块系统成员都应该有的，我们建立一个角色为系统默认角色，把所有默认访问的模块的浏览权加入到里面去，则系统成员都能访问这些模块。
<p><strong>D. </strong><strong>直接指定</strong>
<p>a) 直接指定是通过对某个人具体指定一项权限，使其有使用这个权限的能力。直接指定是角色指定的一个简化版，为了是在建立像某个项目的组长这种角色时，省略创建角色这一个步骤，使角色不至于过多。
<p>b) <strong>实例中</strong>：指定某个项目的组长，把组长权指定给某个人。
<p><strong></strong>
<p><strong>针对职位、项目组：</strong>
<p>如果用添加新员工，员工调换职位、项目组，满足了员工会自动继承所在职位、项目组的权限，不需要重新分配权限的功能。
<p><strong>用户管理</strong>
<p>用户可以属于某一个或多个用户组，可以通过对用户组授权，来对组中的所有用户进行权限的授予。一个用户可以属于多个项目组，或担任多个职位。
<p><strong>授权管理</strong>
<p>将一个基本权限或角色授予用户或用户组，使用户或用户组拥有授予权限的字符串，如果角色、职位、项目中存在相同的基本权限，则取其中的一个；如脱离角色、职位、项目组，只是取消用户或用户组的中此角色、职位、项目组所授予的权限。用户所拥有的权限是所有途径授予权限的集合。管理员用户可以查看每个用户的最终权限列表。
<p><strong>权限管理</strong>
<p>基本操作权限与权限组（基本操作权限的集合）的管理。<br />
<img title="OA系统权限管理设计方案" height="408" alt="" src="http://www.blogjava.net/images/blogjava_net/dreamangel/1.GIF" width="615" border="0" />
<p>OA权限管理设计的实现&nbsp;
<p>物理数据模型图如下：
<p><img title=" OA系统权限管理设计方案 - alex_kame - alex_kame的个人主页" height="545" alt="" src="http://www.blogjava.net/images/blogjava_net/dreamangel/2.JPG" width="593" border="0" /><br />
物理数据模型图&nbsp;
<p>根据以上设计思想,权限管理总共需要以下基本表：
<p>tb_User：用户信息基本表；
<p>tb_Department：部门表；
<p>tb_Company：公司表；
<p>tb_Module：系统模块表；
<p>tb_Action：系统中所有操作的动作表；
<p>tb_Permit：由tb_Module与tb_Action两表结合产生的系统基本权限表；
<p>tb_Permit_Group：权限组表，将一模块的中的所有权限划分一个权限组中，可以通过权限组授予用户权限；
<p>tb_Role：角色表，基本权限的集合。无上级与下级之分；
<p>tb_Position：职位表，有上级与下级之分；
<p>tb_Project：项目组表，
<p>tb_Role_Permit：角色授权表；
<p>tb_Postion_Permit：职位授权表；
<p>tb_Project_Permit：项目授权表；
<p>tb_Project_User：项目成员表，IsLead字段代表此成员为项目组长；
<p>tb_Postion_User：职位成员表；
<p>tb_User_Permit：用户授权表，用户ID与角色、职位、项目及直接授予的权限串表；
<p>权限的产生：
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由tb_Module中的ModuleCode与tb_Action中的ActionCode组成
<p>权限代码PermitCode=ModuleCode+ActionCode。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实例：ModuleCode=0101，ActionCode=01,则PermitCode=010101。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 权限值则有ModuleValue与ActionCode组合而成，采用下划线来连接。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实例：ModuleValue=Sys_User,ActionValue=AdD，PermitValue= Sys_User_Add
<p>权限组：
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 包括一组同一模块下的权限的组合，如管理用户包括基本的权限：添加、删除、修改、查看等，将这些组合起来构成一个用户组——&#8220;用户管理&#8221;权限组。其它类似。只是为了更方便的查看系统权限与权限的分配。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实例：如管理用户的权限代码为010101&#224;查看用户，010102&#224;添加用户,010103&#224;删除用户，010104&#224;修改用户，010105&#224;审核用户等，将这些基本权限组合起来一个集合而构成了&#8220;用户管理&#8221;权限组。
<p>角色、职位、项目：
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 也就是按特定的需要划分一种权限的集合。使用角色授权表、职位授权表、项目授权表来实现。授权表中存放的是权限代码PermitCode,而不是权限组的GroupCode代码。
<p>用户授权：
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由用户授权表来实现，用户授权表中的RoleCode、PositionCode、ProjectCode分别是角色表中RoleCode组成的串、职位表PositionCode组成的串、ProjectCode组成的串。与角色授权表中的角色代码RoleCode、职位授权表中PositionCode、项目授权表中的ProjectCode不对应（不是主表与从表之间外键关系）。
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从而能够实现了一个用户可以拥有多个角色、多个职位、多个项目的情况。
<p>用户授权表中的PermitCode为直接授权的权限代码串，直接给用户分配权限。
<p>实例：
<p>用户ID为UserId=1的用户权限授权表的记录为：
<p>RoleCode=001,003
<p>PostionCode = 001,002
<p>ProjectCode=001,005
<p>PermitCode = 010101,020102
<p>表明此用户拥有两个角色，代码为001和003，并继承这两个角色的权限；
<p>担任两个职位，代码为001与002，并继承两个职位的权限；
<p>属于两个项目组中的成员，项目代码为001与005，并继承两个项目中的权限。<br />
直接指定给用户的权限为010101与010102这两个权限代码的权限
<p>用户权限字符串：
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 根据用户授权表的角色代码、职位代码、项目代码得到权限字符串及表中直接分配的权限字符串组合成一个用户的所有权限字符串集合。</p>
<img src ="http://www.blogjava.net/DreamAngel/aggbug/254641.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/DreamAngel/" target="_blank">飞翔天使</a> 2009-02-14 10:18 <a href="http://www.blogjava.net/DreamAngel/archive/2009/02/14/254641.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>三种权限设计方案的归纳和比较</title><link>http://www.blogjava.net/DreamAngel/archive/2009/02/04/253181.html</link><dc:creator>飞翔天使</dc:creator><author>飞翔天使</author><pubDate>Wed, 04 Feb 2009 02:13:00 GMT</pubDate><guid>http://www.blogjava.net/DreamAngel/archive/2009/02/04/253181.html</guid><wfw:comment>http://www.blogjava.net/DreamAngel/comments/253181.html</wfw:comment><comments>http://www.blogjava.net/DreamAngel/archive/2009/02/04/253181.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/DreamAngel/comments/commentRss/253181.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/DreamAngel/services/trackbacks/253181.html</trackback:ping><description><![CDATA[<p>权限设计是很多系统重要的组成部分，主要用于控制功能和流程，本文将几种常见的权限设计方案（权限系统的名都是自己起的）的基本设计写出来，其中不恰当处还请大家指出，我们来讨论一下.</p>
<p><em><strong>1.等级权限系统</strong></em></p>
<p><strong>&nbsp;&nbsp;&nbsp; </strong>这种权限系统在论坛中很常见，在这种系统中，权限级别如同官阶从低到高排列，每个用户拥有一个权限，其中设定了这个用户的权限等级，在用户需要执行操作前先查看其权限等级是否大于执行操作所需要的权限等级，是则进行操作。</p>
<p>在等级权限系统中领域对象用户类User的基本属性如下：<br />
<strong>&nbsp;&nbsp;&nbsp; id &nbsp;&nbsp;&nbsp; &nbsp; // 用户ID<br />
&nbsp;&nbsp;&nbsp; name &nbsp;&nbsp;&nbsp; // 用户名</strong></p>
<p>领域对象权限类Privilege的基本属性如下:<br />
<strong>&nbsp;&nbsp;&nbsp; id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 权限ID<br />
&nbsp;&nbsp;&nbsp; userid&nbsp;&nbsp; // 持有此权限的用户id<br />
&nbsp;&nbsp;&nbsp; level&nbsp;&nbsp;&nbsp; // 用户的权限等级</strong></p>
<p>level的设置示例<br />
level&nbsp;对应可执行的功能<br />
0&nbsp;访问<br />
1&nbsp;可跟帖<br />
2&nbsp;可创建主贴<br />
3&nbsp;可删除主贴<br />
4&nbsp;可创建频道<br />
5&nbsp;可删除频道<br />
6&nbsp;可查看用户<br />
7&nbsp;可分配用户权限<br />
8&nbsp;可修改用户密码<br />
9&nbsp;可删除用户<br />
...</p>
<p>使用中,执行一个操作比如创建主贴时,先从Session中取出用户,然后按其id查出其对应的权限等级,拿它和执行创建主贴所需要的等级(3)进行比较,高于则可进行创建主贴操作,否则报告权限不够.</p>
<p>等级权限系统简单易用,在如论坛等刚性控制系统中使用很好,但不适用于需要限制权限的范围的场合。</p>
<p><em><strong>2.范围限制权限系统</strong></em><br />
<br />
&nbsp;&nbsp;&nbsp; 等级权限系统系统的缺点是控制范围过广,比如一个论坛中有很多子论坛,一个子论坛的分版主同时也能对另一个同等级分论坛的帖子进行控制,这在一定程度不合理，有越界的嫌疑,更好的做法是将版主权限控制在一版之内,这时我们可以采用范围限制权限系统. 这种权限系统在项目管理系统中很常见.</p>
<p>在等级权限系统中领域对象用户类User的基本属性如下：<br />
<em><strong>&nbsp;&nbsp;&nbsp; id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 用户ID<br />
&nbsp;&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp; // 用户名</strong></em></p>
<p>领域对象项目类Project的基本属性如下：<br />
<em><strong>&nbsp;&nbsp;&nbsp; id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 项目ID<br />
&nbsp;&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp; // 项目名</strong></em></p>
<p>领域对象权限类Privilege的基本属性如下:<br />
<em><strong>&nbsp;&nbsp;&nbsp; id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 权限ID<br />
&nbsp;&nbsp;&nbsp; userid&nbsp;&nbsp; // 持有此权限的用户id<br />
&nbsp;&nbsp;&nbsp; projectid&nbsp;// 此权限对应的项目<br />
&nbsp;&nbsp;&nbsp; level&nbsp;&nbsp;&nbsp;&nbsp; // 用户的权限等级<br />
</strong></em><br />
其中,通过引入了新属性projectid,我们对权限的范围进行了有效限制,项目不同则权限等级再高也是无效,这样就起到了限制权限能力范围的作用.</p>
<p><em><strong>3.范围限制单项权限系统</strong></em></p>
<p><strong></strong>在上面两个权限系统中,权限高的自然能执行权限要求低的操作,这样做权力没有细分,在有些场合并不合理,比如即使是董事长不可直接操作人事部的招聘任务,他只对雇员去留有建议权.对于这样的场合我们需要使用范围限制单项权限系统.它的典型应用如工作流和OA系统。</p>
<p>在范围限制单项权限系统中领域对象用户类User的基本属性如下：<br />
<em><strong>&nbsp;&nbsp;&nbsp; id&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 用户ID<br />
&nbsp;&nbsp;&nbsp; name&nbsp; &nbsp;&nbsp;&nbsp; // 用户名</strong></em></p>
<p>领域对象项目类Project的基本属性如下：<br />
<em><strong>&nbsp;&nbsp;&nbsp; id&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 项目ID<br />
&nbsp;&nbsp;&nbsp; name&nbsp; &nbsp;&nbsp;&nbsp; // 项目名</strong></em></p>
<p>领域对象权限类Privilege的基本属性如下:<br />
<em><strong>&nbsp;&nbsp;&nbsp; id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 权限ID<br />
&nbsp;&nbsp;&nbsp; userid&nbsp;&nbsp;&nbsp;&nbsp; // 持有此权限的用户id<br />
&nbsp;&nbsp;&nbsp; projectid&nbsp; // 此权限对应的项目<br />
&nbsp;&nbsp;&nbsp; abilityid&nbsp; // 权限控制能力id</strong></em></p>
<p>领域对象权限控制能力类ability的基本属性如下:<br />
<em><strong>&nbsp;&nbsp;&nbsp; id &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 控制能力ID<br />
&nbsp;&nbsp;&nbsp; item &nbsp;&nbsp;&nbsp; &nbsp; // 控制能力子项</strong></em></p>
<p>item的设置示例<br />
item&nbsp;对应可执行的功能<br />
0&nbsp;读<br />
1&nbsp;写<br />
2&nbsp;查<br />
3&nbsp;删</p>
<p>...</p>
<p>通过对权限能力的细分,用户权限的控制粒度更细了,对功能和流程就能有更精确的把握,适用于复杂的场合.</p>
<p>以上三种权限系统没有优劣之分只有适用场合的区别,前面的粗略但易于操作,后面的精确但失之烦琐,在现实使用中我们应该根据场合选择合适的权限系统.</p>
<img src ="http://www.blogjava.net/DreamAngel/aggbug/253181.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/DreamAngel/" target="_blank">飞翔天使</a> 2009-02-04 10:13 <a href="http://www.blogjava.net/DreamAngel/archive/2009/02/04/253181.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>