刘政道 - 应用程序框架

《31天学会CRM项目开发(C#编程入门及项目实战)》作者,IT经理,程序员
  博客园  :: 新随笔  :: 联系 :: 管理

Web程序权限设计思考

Posted on 2011-08-23 08:06  刘政道  阅读(943)  评论(0编辑  收藏  举报
1、操作权限
1.1基本操作权限,例如增删改
1.2页面权限,针对每个页面的控制,页面中具体区域的权限控制
1.3菜单权限,或称模块权限,对应一个或多个菜单。

2.数据权限,控制到记录行
2.1自己只能浏览和修改自己的数据
2.2具备权限的可以浏览或修改所有的权限

角色表
ID_,roleName,roleDesc

权限代码表
ID_,opCode,opName,opDesc
1,1001,系统管理,系统管理
2,100101,系统管理-单位管理,系统管理-单位管理
3,100102,系统管理-部门管理,系统管理-部门管理
4,100103,系统管理-帐号管理,系统管理-帐号管理
...
10,2001,新闻管理,新闻管理
11,200101,新闻管理-浏览,新闻管理-浏览
12,200102,新闻管理-增删改,新闻管理-增删改
13,200103,新闻管理-审批,新闻管理-审核
其中,1001应理解为模块权限或页面权限,200102应理解为操作权限

权限角色表,给指定的角色设置权限
ID_,opId,roleId

角色用户表,给指定的帐号设置角色
ID_,roleId,userId

通过sql查询出指定帐号的权限列表
opCode,hasOp
1001,true
200101,flase
....

sql:
SELECT o.opName,r.roleId FROM core_op o
left join core_op_role_relation r on r.opId = o.ID_ and r.roleId in (select u.roleId from core_role_user_relation u where u.userId = 1)


将权限清单加入Session,构造一个方法Map 和 Boolean hasOp(String userId,String opCode)
在jsf页面中通过EL表达式来进行权限控制
比如,rendered="#{NySession.hasOp['200101']=='true'}"
在jsp页面中通过if(hasOp('userId','200101')){}来判断
在javabean中,也是通过hasOp来判断。

用户登录时创建Map,退出时清空Map。

那么记录行权限如何判断呢?
我们在业务表中设置一个CID_字段,记录这条记录的创建者。如果业务限定只有自己可以浏览或修改的话,就将当前帐号的id作为业务表sql的查询条件。具备权限的,通过if(hasOp())判断后进而决定是否追加查询限制条件。

对于更加复杂的记录行控制需求,我们需要设置一个权限表
例如有业务表document,希望可以针对帐号和角色设置访问或修改权限。
我们需要设置两张张权限表document_op_user和document_op_role,例如ID_,docId,userId,在hasOp判断之后就可以决定是否在查询语句中加入限定条件。

限定条件的sql语句一般这么写:
select doc.*
from core_document doc
where (doc.CID_ = :userId
or exists (select 1 from core_document_role_relation r where r.roleId in (SELECT role.roleId FROM core_role_user_relation role where role.userId = :userId) and r.docId = doc.ID_)
or exists (select 1 from core_document_user_relation u where u.userId = :userId and u.docId = doc.ID_))

对于复杂的sql可以写成存储过程。上面只是控制到了记录行的访问权限,要想控制增删改权限需要借助操作权限控制。

菜单权限和上述权限类似,通过一条sql来查询当前帐号的菜单权限。

由于MiniOA是开源的,所以MiniOA的每一个页面和按钮都会有权限控制,当然,如果只是单个项目,权限控制不必那么严格。

欢迎斧正