在任何系统中,权限设计是最基础的东西,本文给出一个基于角色的权限设计的循序渐进的设计方案。
在权限系统中,功能(权限)是最小的单位,比如起草新闻、编辑新闻、审核新闻、删除新闻等,而角色是一类功能的集合,比如新闻编辑这个角色,他可能有起草新闻、编辑新闻等功能集合,而责任编辑他可能就有更多的权限,比如除了新闻编辑的功能,还有审核新闻、删除新闻等功能,给张三赋予新闻编辑的角色(其实我更愿意说把张三加入到新闻编辑这个角色中去),张三就可以起草新闻、编辑新闻了,给李四赋予责任编辑的角色,李四就可以起草新闻、编辑新闻、审核新闻、删除新闻了。
我们来看看版本一的解决方案:
我们来模拟一下上面的数据:
用户信息表:
UserID | UserName |
U1 | 张三 |
U2 | 李四 |
角色表:
RoleID | RoleName |
R1 | 新闻编辑 |
R2 | 责任编辑 |
角色用户表:
RoleID | UserID |
R1 | U1 |
R2 | U2 |
功能表:
FunctionID | FunctionName |
F1 | 起草新闻 |
F2 | 编辑新闻 |
F3 | 审核新闻 |
F4 | 删除新闻 |
角色功能表:
RoleID | FunctionID |
R1 | F1 |
R1 | F2 |
R2 | F1 |
R2 | F2 |
R2 | F3 |
R2 | F4 |
我们来看看如何判断一个用户具有某个功能权限:
首先在用户张三登录的时候,获取张三的全部功能列表:
Select FunctionID From 角色功能表 Where RoleID In (Select RoleID From 用户角色表 Where UserID=’U 1’ )
这样就可以得到张三的全部功能列表Functions,在起草新闻的页面我们就可以做如下判断:
Functions.Contain(‘F 1’ );//当然你可以把这个’F 1’ 定义成一个常量:NewsFunction.Draft
如果为true就说明张三有起草新闻的权限。
当然对于web应用,您可以把Functions 用session保存起来,以避免每打开一个页面都去数据库中获取。
似乎看起来是一个不错的解决方案。
还是新闻系统,最初新闻系统没有分类,但是随着新闻的增加,没有分类的新闻看起来总是乱的,于是张三和李四给新闻添加了分类A、分类B,还是由张三负责起草,李四负责审核,以后又添加了更多的分类,并且也增加了人手,这个时候就有新的要求出来了:希望张三只负责分类A的起草,分类B的起草交给其他人做,李四呢也只负责分类A的审核(就相当于是一个栏目的责任编辑)。
样的需求,版本一就无能为力了(当然你也可以增加几个功能:比如分类A的新闻起草和分类B的新闻起草,再把这个功能添加到相应的角色里面去,但是这个应该不是我们要得解决方案吧,不过版本二也是基于这个思想来解决的)。
其实比新闻更好的例子是论坛板块的版主。
下面是版本二的解决方案:
在版本二的功能表中加入了一个ResourceType这个字段,这个字段用来表示对某个资源的分类(比如新闻),我们同样来模拟一下(新闻分类A的ResourceType为:NTA,分类B为:NTB):
功能表:
FunctionID | ResourceType | FunctionName |
F1 | NTA | 起草新闻:分类A |
F2 | NTA | 编辑新闻:分类A |
F3 | NTA | 审核新闻:分类A |
F4 | NTA | 删除新闻:分类A |
F1 | NTB | 起草新闻:分类B |
F2 | NTB | 编辑新闻:分类B |
F3 | NTB | 审核新闻:分类B |
F4 | NTB | 删除新闻:分类B |
然后在角色表添加相应的角色,在角色功能表中添加对应的功能。
获取Functions的语句也相应地做变化:
Select FunctionID + ‘,’ + ResourceType From 角色功能表 Where RoleID In (Select RoleID From 用户角色表 Where UserID=’U 1’ )
权限的判断也就变成:
Functions.Contain(‘F1,NTA’);
在新添加一个分类的时候,同时也在功能表中增加相应的记录(当然不是在数据库里面直接添加,由和功能相关的函数来添加)。
使用这种解决方案可以简单地对有分类的应用(比如论坛系统)的每个分类实行不同的控制(比如VIP板块,就只能拥有VIP角色的用户才能浏览、发表等,而其他板块只要是注册用户就可以使用了)。
在实际应用中FunctionID并不是随便的一个字符串,而是进行了编码,其编码中包含了模块ID以及能够体现出父子关系,举个例子来说:对于论坛系统,我们给它一个模块ID为” 30” ,论坛的功能我们先分成2类,一类是管理类(比如删除帖子),一类是使用类(比如发帖、回帖、浏览帖子等),给管理类一个编码:01,使用类一个编码:02,我们就对FunctionID进行如下的编码:
300101:删除帖子
300201:发帖
300202:回帖
300203:浏览帖子
对于资源(比如某个板块1,板块的ID为:01),我们可以组合出如下的Functions(当然这个组合你也可以不用逗号分隔,用其他的组合方式也可以,不过不要产生歧义):
300101,01:板块1删除帖子的功能
300201,01:板块1发帖的功能
……
对于RoleID也是采用的编码方式,也能体现角色的父子关系,也可以实现角色功能的继承等(当然获取角色功能列表的SQL语句就不是现在这么简单了)。在我现在的应用里面没有实现角色的继承(虽然角色的编码体现出了角色的父子关系)。
公司概述
上海互联网软件有限公司由直属科技部的国家火炬互联网创业中心技术应用服务中心转制而来。该机构为科技部863火炬计划之一,其宗旨在于探索以互联网为代表的新经济在中国的成长与发展之路。公司以"服务于政府信息化建设"为使命,致力于"做专业的电子政务系统软件提供商,全力打造信息时代政府办公新模式"。由于公司背景上的优势,和几年来在电子政务领域的不断努力,使公司积累了一系列适合政府部门实际应用的系统设计和业务流程设计方面的经验。
商业挑战
随着信息化建设的推进,各区县的信息化水平正在不断提升。截至目前,在各区县的信息化环境中已经建设了众多的应用系统并投入日常的办公使用,这些应用系统已经成为电子政务的重要组成部分。
各区县的信息体系中的现存应用系统是由不同的开发商在不同的时期采用不同的技术建设的,如:邮件系统、政府内部办公系统、公文管理系统、呼叫系统、GIS系统等。这些应用系统中,大多数都有自成一体的用户管理、授权及认证系统,同一用户在进入不同的应用系统时都需要使用属于该系统的不同账号去访问不同的应用系统,这种操作方式不仅为用户的使用带来许多不便,更重要的是降低了电子政务体系的可管理性和安全性。
与此同时,各区县正在不断建设新的应用系统,以进一步提高信息化的程度和电子政务的水平。这些新建的应用系统也存在用户认证、管理和授权的问题。
在推进和发展电子政务建设的进程中,需要通过统一规划和设计,开发建设一套统一的授权管理和用户统一的身份管理及单点认证支撑平台。利用此支撑平台可以实现用户一次登录、网内通用,避免多次登录到多个应用的情况。此外,可以对区域内各信息应用系统的权限分配和权限变更进行有效的统一化管理,实现多层次统一授权,审计各种权限的使用情况,防止信息共享后的权限滥用,规范今后的应用系统的建设。
为此,我公司开发设计了统一用户及权限管理系统1.0版,该系统以用户为中心,为了确保用户安全可靠的访问相应的功能和信息,统一用户及权限管理系统包含了统一用户管理(UUM)子模块来对注册的用户进行管理。统一用户及权限管理系统在用户组之间定义操作权限,定义用户可以访问哪些数据、哪些应用,支持用户的单点登录。
针对用户的需求,为了能够满足用户在灵活性、可靠性、安全性以及效率等方面的要求,我公司设计出统一用户及权限管理系统的完整系统框架,我们选择了Microsoft Visual Studio.Net 作为我们的开发工具,采用C#编程语言编写asp.net web客户端,作为系统的展现层。
解决方案
系统介绍
统一用户及权限管理系统的拓扑结构如下:
统一用户及权限管理系统的逻辑结构如下:
该系统采用VS.Net体系结构,采用C#编程语言,Sql Server2000数据库开发基于b/s结构的权限管理系统,该系统包括以下4个功能模块,每个模块又包含了几个到十几个不等的功能组,实现了权限管理所需的常用功能,其功能组成大致如下:
模块 | 功能组 |
登录页 | 登录页 |
用户授权管理 | 用户基本信息管理、用户包含的角色管理、用户包含的权限管理、用户组织机构管理、用户岗位管理 |
组织机构管理 | 组织机构基本信息管理、岗位基本信息管理、岗位包含的权限管理、岗位认证管理、拥有岗位的用户管理 |
应用权限定制 | 应用系统基本信息管理、应用系统权限组管理、应用系统权限管理、应用系统角色管理 |
系统维护 | 查询系统审计、查询应用审计 |
系统界面实例
首页
新增用户
用户查询
设置用户角色
本系统的开发工作从2003年11月中旬到2004年2月底,耗时3个月,由五位工程师参与此项工作,到2月底已基本完成了系统的开发,从3月初开始,已在徐汇区现场实施,在现场实施过程中,并在实施的过程中针对用户的管理思路,对系统作了一定的调整,进一步完善了系统,目前,系统已经在徐汇区得到了很好的应用。
商业收益
1. | 增强的性能:ASP.NET 是在服务器上运行的编译好的公共语言运行库代码。与被解释的前辈不同,ASP.NET 可利用早期绑定、实时编译、本机优化和盒外缓存服务。这相当于在编写代码行之前便显著提高了性能。 |
2. | 世界级的工具支持:ASP.NET 框架补充了 Visual Studio 集成开发环境中的大量工具箱和设计器。WYSIWYG 编辑、拖放服务器控件和自动部署只是这个强大的工具所提供功能中的少数几种。 |
3. | 威力和灵活性:由于 ASP.NET 基于公共语言运行库,因此 Web 应用程序开发人员可以利用整个平台的威力和灵活性。.NET 框架类库、消息处理和数据访问解决方案都可从 Web 无缝访问。ASP.NET 也与语言无关,所以可以选择最适合应用程序的语言,或跨多种语言分割应用程序。另外,公共语言运行库的交互性保证在迁移到 ASP.NET 时保留基于 COM 的开发中的现有投资。 |
4. | 简易性:ASP.NET 使执行常见任务变得容易,从简单的窗体提交和客户端身份验证到部署和站点配置。例如,ASP.NET 页框架使您可以生成将应用程序逻辑与表示代码清楚分开的用户界面,和在类似 Visual Basic 的简单窗体处理模型中处理事件。另外,公共语言运行库利用托管代码服务(如自动引用计数和垃圾回收)简化了开发。 |
5. | 可管理性:ASP.NET 采用基于文本的分层配置系统,简化了将设置应用于服务器环境和 Web 应用程序。由于配置信息是以纯文本形式存储的,因此可以在没有本地管理工具帮助的情况下应用新设置。此"零本地管理"哲学也扩展到了 ASP.NET 框架应用程序的部署。只需将必要的文件复制到服务器,即可将 ASP.NET 框架应用程序部署到服务器。不需要重新启动服务器,即使是在部署或替换运行的编译代码时。 |
6. | 可缩放性和可用性:ASP.NET 在设计时考虑了可缩放性,增加了专门用于在聚集环境和多处理器环境中提高性能的功能。另外,进程受到 ASP.NET 运行库的密切监视和管理,以便当进程行为不正常(泄漏、死锁)时,可就地创建新进程,以帮助保持应用程序始终可用于处理请求。 |
7. | 自定义性和扩展性:ASP.NET 随附了一个设计周到的结构,它使开发人员可以在适当的级别"插入"代码。实际上,可以用自己编写的自定义组件扩展或替换 ASP.NET 运行库的任何子组件。实现自定义身份验证或状态服务一直没有变得更容易。 |
8. | 安全性:借助内置的 Windows 身份验证和基于每个应用程序的配置,可以保证应用程序是安全的。 |