分类: 软件技术 2006-11-21 11:11 5312人阅读 评论(0) 收藏 举报
通用数据权限管理系统设计(一)
作者:逸云
前言:
本文提供一种集成功能权限和数据权限的解决方法,以满足多层次组织中权限管理方面的集中控制。本方法是RBAC(基于角色的访问控制方法)的进一步扩展和延伸,即在功能权限的基础上增加数据权限的管理,实现数据权限和功能权限的集中处理。
解释:
功能权限:能做什么的问题,如增加销售订单;
数据权限:能在哪里干什么的问题,如察看北京分公司海淀销售部张三的销售订单;
术语:
资源:系统中的资源,主要是各种业务对象,如销售单、付款单等;
操作类型:对资源可能的访问方法,如增加、删除、修改等;
功能:对资源的操作,是资源与操作类型的二元组,如增加销售单、修改销售单等;
数据类型:业务系统中常用的数据权限类型,如公司、部门、项目、个人等;
数据对象:具体的业务对象,如甲公司、乙部门等等,包括所有涉及到数据权限的对象值;
权限:角色可使用的功能,分角色的功能权限和角色的数据权限;
角色:特定权限的集合;
用户:参与系统活动的主体,如人,系统等。
通用数据权限管理系统设计(二)
方法说明:
在实际应用中,数据权限的控制点一般相对固定,如针对公司、部门、个人、客户、供应商等,也就是说数据权限一般针对指定数据类型下的一些数据对象。
本方法中,数据权限的依赖于功能权限,是对功能权限的进一步描述,说明角色在指定的功能点上的数据控制权限。
本方法中采用“没有明确规定即视为有效”的原则,如果没有定义功能的数据权限,则说明该角色具有该功能的全部的权限。如果定义了功能的某种类型的数据权限,则该用户只具有该类型下指定数据的数据权限。
这段话比较绕口,下面举个例子实际例子。
某公司有北京销售部、上海销售部和广州销售部三个销售部,现在需要定义几种角色:
销售总监 -- 能察看所有销售部的销售订单;
北京销售经理 -- 只能察看北京销售部的所有销售订单;
上海销售经理 -- 只能察看上海销售部的所有销售订单;
广州销售经理 -- 只能察看广州销售部的所有销售订单;
上述角色的定义如下:
-------------------------------------------------------------------
角色名称 功能 数据类型 数据对象
-------------------------------------------------------------------
销售总监 察看销售订单
北京销售经理 察看销售订单 部门 北京
上海销售经理 察看销售订单 部门 上海
广州销售经理 察看销售订单 部门 广州
-------------------------------------------------------------------
上述定义中,销售总监只定义了功能权限,而没有定义数据权限,所以销售总监能够察看所有的销售订单;而其他几位销售经理分别定义了这一功能的数据权限,所以只能察看指定部门的销售订单。
在实际应用中,往往会出现部门分组,组长能够察看本组所有人员处理的销售订单的情况,以及某些情况下,某些人只能察看本人的销售订单的情况,这些特殊情况在上述的说明中无法解决,需要在设计和实现中进行处理。
北京销售代表 -- 只能察看北京销售部的本人的所有销售订单;
北京销售代表 察看销售订单 部门 北京
个人
通用数据权限管理系统设计(三)--数据库设计
我们先来看看传统的基于角色的权限管理系统,如下图所示,最简单的基于角色的权限管理由系统功能、系统角色、系统用户、角色功能和用户角色五部分组成。
图一:基于角色的数据库结构
为实现数据权限控制,在设计上对基于角色的权限管理进行扩充,如下图所示:
图二:通用数据权限管理系统数据库设计
对比两张图,我们可以看到,他们之间的主要变化为:
1、 增加系统资源信息和操作类型信息,系统资源为树形结构、如销售模块、销售订单等;操作类型记录可能的操作,如增加、删除、修改、查看、查询等,系统功能是资源与操作类型的组合,对资源的操作就是系统功能。
2、 增加数据对象类型和数据对象两张表,数据对象类型记录系统中需要控制的对象类型,如部门、库房、员工、客户、供应商等;数据对象记录各对象类型的对象实例,如北京销售部、上海销售部、张三、李四等等。(保存的好处后面会说到)
3、 增加系统资源与数据对象类型的关联表(多对多),本表为配置表,说明某种资源可能需要的控制点,如销售订单与部门类型的关联可能涉及到分部门分配权限;销售订单与客户的关联可能涉及到按客户分配权限等等。
4、 增加数据对象与角色权限的关联,这张表是真正最终实现数据权限管理的所在地。
通过这种设计,能够最小化地减少对原有权限系统的更改,并且可以很灵活地增加数据的控制点。在产品化软件的设计中使用,能够灵活满足客户的需要。
用户权限设计(四)——基于RBAC模型的通用权限管理系统的设计(数据模型)的扩展【转】
分类: 软件技术 2006-11-22 10:41 3511人阅读 评论(0) 收藏 举报
1 RBAC模型
访问控制是针对越权使用资源的防御措施。基本目标是为了访问主体(用户、进程、服务等)对访问客体(文件、系统等)的访问权限,从而使计算机系统在合法范围内使用;决定用户能做什么,也决定代表一定用户利益的程序能做什么[1]。
企业环境中的访问控制策略一般有三种:自主型访问控制方法、强制型访问控制方法和基于角色的访问控制方法(RBAC)。其中,自主式太弱,强制式太强,二者工作量大,不便于管理[1]。基于角色的访问控制方法是目前公认的解决大型企业的统一资源访问控制的有效方法。其显著的两大特征是:1.减小授权管理的复杂性,降低管理开销;2.灵活地支持企业的安全策略,并对企业的变化有很大的伸缩性。
NIST(The National Institute of Standards and Technology,美国国家标准与技术研究院)标准RBAC模型由4个部件模型组成,这4个部件模型分别是基本模型RBAC0(Core RBAC)、角色分级模型RBAC1(Hierarchal RBAC)、角色模型RBAC2(Constraint RBAC)和统一模型RBAC3(Combines RBAC)[1]。RBAC0模型如图1所示。
a. RBAC0定义了能构成一个RBAC控制系统的最小的元素集合。在RBAC之中,包含用户users(USERS)、角色roles(ROLES)、目标objects(OBS)、操作operations(OPS)、许可权permissions(PRMS)五个基本数据元素,权限被赋予角色,而不是用户,当一个角色被指定给一个用户时,此用户就拥有了该角色所包含的权限。会话sessions是用户与激活的角色集合之间的映射。RBAC0与传统访问控制的差别在于增加一层间接性带来了灵活性,RBAC1、RBAC2、RBAC3都是先后在RBAC0上的扩展。
b. RBAC1引入角色间的继承关系,角色间的继承关系可分为一般继承关系和受限继承关系。一般继承关系仅要求角色继承关系是一个绝对偏序关系,允许角色间的多继承。而受限继承关系则进一步要求角色继承关系是一个树结构。
c. RBAC2模型中添加了责任分离关系。RBAC2的约束规定了权限被赋予角色时,或角色被赋予用户时,以及当用户在某一时刻激活一个角色时所应遵循的强制性规则。责任分离包括静态责任分离和动态责任分离。约束与用户-角色-权限关系一起决定了RBAC2模型中用户的访问许可。
d. RBAC3包含了RBAC1和RBAC2,既提供了角色间的继承关系,又提供了责任分离关系。
2核心对象模型设计
根据RBAC模型的权限设计思想,建立权限管理系统的核心对象模型.对象模型中包含的基本元素主要有:用户(Users)、用户组(Group)、角色(Role)、目标(Objects)、访问模式(Access Mode)、操作(Operator)。主要的关系有:分配角色权限PA(Permission Assignment)、分配用户角色UA(Users Assignmen描述如下:
a .控制对象:是系统所要保护的资源(Resource),可以被访问的对象。资源的定义需要注意以下两个问题:
1.资源具有层次关系和包含关系。例如,网页是资源,网页上的按钮、文本框等对象也是资源,是网页节点的子节点,如可以访问按钮,则必须能够访问页面。
2.这里提及的资源概念是指资源的类别(Resource Class),不是某个特定资源的实例(Resource Instance)。资源的类别和资源的实例的区分,以及资源的粒度的细分,有利于确定权限管理系统和应用系统之间的管理边界,权限管理系统需要对于资源的类别进行权限管理,而应用系统需要对特定资源的实例进行权限管理。两者的区分主要是基于以下两点考虑:
一方面,资源实例的权限常具有资源的相关性。即根据资源实例和访问资源的主体之间的关联关系,才可能进行资源的实例权限判断。 例如,在管理信息系统中,需要按照营业区域划分不同部门的客户,A区和B区都具有修改客户资料这一受控的资源,这里“客户档案资料”是属于资源的类别的范畴。如果规定A区只能修改A区管理的客户资料,就必须要区分出资料的归属,这里的资源是属于资源实例的范畴。客户档案(资源)本身应该有其使用者的信息(客户资料可能就含有营业区域这一属性),才能区分特定资源的实例操作,可以修改属于自己管辖的信息内容。
另一方面,资源的实例权限常具有相当大的业务逻辑相关性。对不同的业务逻辑,常常意味着完全不同的权限判定原则和策略。
b.权限:对受保护的资源操作的访问许可(Access Permission),是绑定在特定的资源实例上的。对应地,访问策略(Access Strategy)和资源类别相关,不同的资源类别可能采用不同的访问模式(Access Mode)。例如,页面具有能打开、不能打开的访问模式,按钮具有可用、不可用的访问模式,文本编辑框具有可编辑、不可编辑的访问模式。同一资源的访问策略可能存在排斥和包含关系。例如,某个数据集的可修改访问模式就包含了可查询访问模式。
c.用户:是权限的拥有者或主体。用户和权限实现分离,通过授权管理进行绑定。
d.用户组:一组用户的集合。在业务逻辑的判断中,可以实现基于个人身份或组的身份进行判断。系统弱化了用户组的概念,主要实现用户(个人的身份)的方式。
e.角色:权限分配的单位与载体。角色通过继承关系支持分级的权限实现。例如,科长角色同时具有科长角色、科内不同业务人员角色。
f.操作:完成资源的类别和访问策略之间的绑定。
g.分配角色权限PA:实现操作和角色之间的关联关系映射。
h.分配用户角色UA:实现用户和角色之间的关联关系映射。
该对象模型最终将访问控制模型转化为访问矩阵形式。访问矩阵中的行对应于用户,列对应于操作,每个矩阵元素规定了相应的角色,对应于相应的目标被准予的访问许可、实施行为。按访问矩阵中的行看,是访问能力表CL(Access Capabilities)的内容;按访问矩阵中的列看,是访问控制表ACL(Access Control Lists)的内容。
数据模型图如下:
用户权限设计(二)——用户认证管理设计方案【转】
用户认证管理设计方案
1 设计思路
为了设计一套具有较强可扩展性的用户认证管理,需要建立用户、角色和权限等数据库表,并且建立之间的关系,具体实现如下。
1.1 用户
用户仅仅是纯粹的用户,用来记录用户相关信息,如用户名、密码等,权限是被分离出去了的。用户(User)要拥有对某种资源的权限,必须通过角色(Role)去关联。
用户通常具有以下属性:
ü 编号,在系统中唯一。
ü 名称,在系统中唯一。
ü 用户口令。
ü 注释,描述用户或角色的信息。
1.2 角色
角色是使用权限的基本单位,拥有一定数量的权限,通过角色赋予用户权限,通常具有以下属性:
ü 编号,在系统中唯一。
ü 名称,在系统中唯一。
ü 注释,描述角色信息
1.3 权限
权限指用户根据角色获得对程序某些功能的操作,例如对文件的读、写、修改和删除功能,通常具有以下属性:
ü 编号,在系统中唯一。
ü 名称,在系统中唯一。
ü 注释,描述权限信息
1.4 用户与角色的关系
一个用户(User)可以隶属于多个角色(Role),一个角色组也可拥有多个用户,用户角色就是用来描述他们之间隶属关系的对象。用户(User)通过角色(Role)关联所拥有对某种资源的权限,例如
l 用户(User):
UserID UserName UserPwd
1 张三 xxxxxx
2 李四 xxxxxx
……
l 角色(Role):
RoleID RoleName RoleNote
01 系统管理员 监控系统维护管理员
02 监控人员 在线监控人员
03 调度人员 调度工作人员
04 一般工作人员 工作人员
……
l 用户角色(User_Role):
UserRoleID UserID RoleID UserRoleNote
1 1 01 用户“张三”被分配到角色“系统管理员”
2 2 02 用户“李四”被分配到角色“监控人员”
3 2 03 用户“李四”被分配到角色“调度人员”
……
从该关系表可以看出,用户所拥有的特定资源可以通过用户角色来关联。
1.5 权限与角色的关系
一个角色(Role)可以拥有多个权限(Permission),同样一个权限可分配给多个角色。例如:
l 角色(Role):
RoleID RoleName RoleNote
01 系统管理员 监控系统维护管理员
02 监控人员 在线监控人员
03 调度人员 调度工作人员
04 一般工作人员 工作人员
……
l 权限(Permission):
PermissionID PermissionName PermissionNote
0001 增加监控 允许增加监控对象
0002 修改监控 允许修改监控对象
0003 删除监控 允许删除监控对象
0004 察看监控信息 允许察看监控对象
……
l 角色权限(Role_Permission):
RolePermissionID RoleID PermissionID RolePermissionNote
1 01 0001 角色“系统管理员”具有权限“增加监控”
2 01 0002 角色“系统管理员”具有权限“修改监控”
3 01 0003 角色“系统管理员”具有权限“删除监控”
4 01 0004 角色“系统管理员”具有权限“察看监控”
5 02 0001 角色“监控人员”具有权限“增加监控”
6 02 0004 角色“监控人员”具有权限“察看监控”
……
由以上例子中的角色权限关系可以看出,角色权限可以建立角色和权限之间的对应关系。
1.6 建立用户权限
用户权限系统的核心由以下三部分构成:创造权限、分配权限和使用权限。
第一步由Creator创造权限(Permission),Creator在设计和实现系统时会划分。利用存储过程CreatePermissionInfo(@PermissionName,@PermissionNote)创建权限信息,指定系统模块具有哪些权限。
第二步由系统管理员(Administrator)创建用户和角色,并且指定用户角色(User-Role)和角色权限(Role-Permission)的关联关系。
1) 具有创建用户、修改用户和删除用户的功能: Administrator
l 存储过程CreateUserInfo(@UserName,@UserPwd)创建用户信息;
l 存储过程ModifyUserInfo(@UserName,@UserPwd)修改用户信息;
l 存储过程DeleteUserInfo(@UserID)删除用户信息;
2) 具有创建角色和删除角色的功能: Administrator
l 存储过程CreateRoleInfo(@RoleName,@RoleNote)创建角色信息;
l 存储过程DeleteRoleInfo(@RoleID)删除角色信息;
3)Administrator具有建立用户和角色、角色和权限的关联关系功能:
l 存储过程GrantUserRole(@UserID,@RoleID,@UserRoleNote)建立用户和角色的关联关系;
l 存储过程DeleteUserRole(@UserRoleID)删除用户和角色的关联关系;
l 存储过程GrantRolePermission(@RoleID,@PermissionID,@RolePermissionNote)建立角色和权限的关联关系;
l 存储过程DeleteRolePermission(@RolePermissionID)删除角色和权限的关联关系;
第三步用户(User)使用Administrator分配给的权限去使用各个系统模块。利用存储过程GetUserRole(@UserID, @UserRoleID output),GetRolePermission(@RoleID,@Role-
-PermissinID output)获得用户对模块的使用权限。
1.7 用户认证实现
当用户通过验证后,由系统自动生成一个128位的TicketID保存到用户数据库表中,建立存储过程Login(@UserID,@UserPwd,@TicketID output)进行用户认证,认证通过得到一个TicketID,否则TicketID为null。其流程图如下:
图1 Login流程图
得到TicketID后,客户端在调用服务端方法时传递TicketID,通过存储过程JudgeTicketPermission(@TicketID,@PermissionID)判断TicketID对应的用户所具有的权限,并根据其权限进行方法调用。
当用户退出系统时,建立存储过程Logout(@UserID)来退出系统。当用户异常退出系统时,根据最后的登陆时间(LastSignTime)确定用户的TickeID,建立存储过程ExceptionLogout(@UserID,@LastSignTime)处理用户的异常退出。
图2 Logout流程图
WebService可以采用SoapHeader中写入TicketID来使得TicketID从客户端传递给服务端。.Net Remoting可以采用CallContext类来实现TicketID从客户端传递给服务端。
2 数据库设计
2.1 数据库表
图3 数据库关系图
2.2 数据库表说明
2.2.1 用户表(Static_User)
Static_User
| Static_User字段名 | 详细解释 | 类型 | 备注 |
| UserID | 路线编号 | varchar(20) | PK |
| UserName | 用户名称 | varchar(20) | |
| UserPwd | 用户密码 | varchar(20) | |
| LastSignTime | 最后登陆时间 | datatime | |
| SignState | 用户登陆状态标记 | int | |
| TickeID | 验证票记录编号 | varchar(128) | |
Static_Role
| Static_User字段名 | 详细解释 | 类型 | 备注 |
| RoleID | 角色编号 | varchar(20) | PK |
| RoleName | 角色名称 | varchar(20) | |
| RoleNote | 角色信息描述 | varchar(20) | |
Static_User_Role
| Static_User字段名 | 详细解释 | 类型 | 备注 |
| UserRoleID | 用户角色编号 | varchar(20) | PK |
| UserID | 用户编号 | varchar(20) | FK |
| RoleID | 角色编号 | varchar(20) | FK |
| UserRoleNote | 用户角色信息描述 | varchar(20) | |
Static_Permission
| Static_User字段名 | 详细解释 | 类型 | 备注 |
| PermissionID | 编号 | varchar(20) | PK |
| PermissionName | 权限名称 | varchar(20) | |
| PermissionNote | 全息信息描述 | varchar(20) | |
Static_Role_Permission
| Static_User字段名 | 详细解释 | 类型 | 备注 |
| RolePermissionID | 角色权限编号 | varchar(20) | PK |
| RoleID | 角色编号 | varchar(20) | FK |
| PermissionID | 权限编号 | varchar(20) | FK |
| RolePermissionNote | 角色权限信息描述 | varchar(20) | |
3.1 WebService SoapHeader
对 SQL 数据库执行自定义身份验证和授权。在这种情况中,应向服务传递自定义凭据(如用户名和密码),并让服务自己处理身份验证和授权。 将额外的信息连同请求一起传递给 XML Web 服务的简便方法是通过 SOAP 标头。为此,需要在服务中定义一个从 SOAPHeader 派生的类,然后将服务的公共字段声明为该类型。这在服务的公共合同中公开,并且当从 WebServiceUtil.exe 创建代理时可由客户端使用,如下例所示:
using System.Web.Services;
using System.Web.Services.Protocols;
// AuthHeader class extends from SoapHeader
public class AuthHeader : SoapHeader {
public string Username;
public string Password;
}
public class HeaderService : WebService {
public AuthHeader sHeader;
...
}
服务中的每个 WebMethod 都可以使用 SoapHeader 自定义属性定义一组关联的标头。默认情况下,标头是必需的,但也可以定义可选标头。SoapHeader 属性指定公共字段的名称或者 Client 或 Server 类的属性(本标题中称为 Headers 属性)。在为输入标头调用方法前,WebService 设置 Headers 属性的值;而当方法为输出标头返回时,WebService 检索该值。
[WebMethod(Description="This method requires a custom soap header set by the caller")]
[SoapHeader("sHeader")]
public string SecureMethod() {
if (sHeader == null)
return "ERROR: Please supply credentials";
else
return "USER: " + sHeader.Username;
}
然后,客户端在调用要求标头的方法之前,直接在代理类上设置标头,如下面的示例所示:
HeaderService h = new HeaderService();
AuthHeader myHeader = new AuthHeader();
myHeader.Username = "username";
myHeader.Password = "password";
h.AuthHeader = myHeader;
String result = h.SecureMethod();
3.2 .Net Remoting的安全认证方式
CallContext提供与执行代码路径一起传送的属性集,CallContext是类似于方法调用的线程本地存储的专用集合对象,并提供对每个逻辑执行线程都唯一的数据槽。数据槽不在其他逻辑线程上的调用上下文之间共享。当 CallContext 沿执行代码路径往返传播并且由该路径中的各个对象检查时,可将对象添加到其中。当对另一个 AppDomain 中的对象进行远程方法调用时,CallContext 类将生成一个与该远程调用一起传播的 LogicalCallContext 实例。只有公开 ILogicalThreadAffinative 接口并存储在 CallContext 中的对象被在 LogicalCallContext 中传播到 AppDomain 外部。不支持此接口的对象不在 LogicalCallContext 实例中与远程方法调用一起传输。
CallContext.SetData方法存储给定对象并将其与指定名称关联,CallContext.GetData方法从 CallContext 中检索具有指定名称的对象。
下面的代码示例说明如何使用 SetData 方法将主体和标识对象传输到远程位置以进行标识。
public class ClientClass {
public static void Main() {
GenericIdentity ident = new GenericIdentity("Bob");
GenericPrincipal prpal = new GenericPrincipal(ident,
Newstring[] {"Level1"});
LogicalCallContextData data =
new LogicalCallContextData(prpal);
//Enter data into the CallContext
CallContext.SetData("test data", data);
Console.WriteLine(data.numOfAccesses);
ChannelServices.RegisterChannel(new TcpChannel());
RemotingConfiguration.RegisterActivatedClientType(
typeof(HelloServiceClass), "tcp://localhost:8082");
HelloServiceClass service = new HelloServiceClass();
if(service == null) {
Console.WriteLine("Could not locate server.");
return;
}
// call remote method
Console.WriteLine();
Console.WriteLine("Calling remote object");
Console.WriteLine(service.HelloMethod("Caveman"));
Console.WriteLine(service.HelloMethod("Spaceman"));
Console.WriteLine(service.HelloMethod("Bob"));
Console.WriteLine("Finished remote object call");
Console.WriteLine();
//Extract the returned data from the call context
LogicalCallContextData returnedData =
(LogicalCallContextData)CallContext.GetData("test data");
Console.WriteLine(data.numOfAccesses);
Console.WriteLine(returnedData.numOfAccesses);
}
}
下面的代码示例说明如何使用 GetData 方法将主体和标识对象传输到远程位置以进行标识。
using System;
using System.Text;
using System.Runtime.Remoting.Messaging;
using System.Security.Principal;
public class HelloServiceClass : MarshalByRefObject {
static int n_instances;
int instanceNum;
public HelloServiceClass() {
n_instances++;
instanceNum = n_instances;
Console.WriteLine(this.GetType().Name + " has been created.
Instance # = {0}", instanceNum);
}
~HelloServiceClass() {
Console.WriteLine("Destroyed instance {0} of
HelloServiceClass.", instanceNum);
}
public String HelloMethod(String name) {
//Extract the call context data
LogicalCallContextData data =
(LogicalCallContextData)CallContext.GetData("test data");
IPrincipal myPrincipal = data.Principal;
//Check the user identity
if(myPrincipal.Identity.Name == "Bob") {
Console.WriteLine("/nHello {0}, you are identified!",
myPrincipal.Identity.Name);
Console.WriteLine(data.numOfAccesses);
}
else {
Console.WriteLine("Go away! You are not identified!");
return String.Empty;
}
// calculate and return result to client
return "Hi there " + name + ".";
}
}
4 详细代码设计
4.1 WebService代码设计
WebService端代码主要进行对数据库的操作,建立起Client操作数据库所需要的方法,供Client的端调用。
1)class UserInfoMng() 用户信息管理类,其中包括方法:
l CreateUserInfo(string UserName string UserPwd) 建立用户信息,调用存储过程CreateUserInfo(@UserName,@UserPwd)
l ModifyUserInfo(string UserName string UserPwd) 修改用户信息,调用存储过程ModifyUserInfo(@UserName,@UserPwd)
l DeleteUserInfo() 删除用户信息,调用存储过程DeleteUserInfo
(@UserID)
2)class UserAuthentication() 用户认证类,用来实现用户角色、权限的设置,包括方法:
l CreatePermissionInfo(string PermissionName string Permissi-
-onNote) 建立权限信息,调用存储过程CreatePermissionInfo
(@PermissionName,@PermissionNote)
l CreateRoleInfo(string RoleName string RoleNote) 建立角色信息,调用存储过程CreateRoleInfo(@RoleName,@RoleNote)
l DeleteRoleInfo() 删除角色信息,调用存储过程DeleteRoleInfo
(@RoleID)
l GrantUserRole(string UserID string RoleID string UserRoleNote) 授予用户角色,调用存储过程GrantUserRole(@UserID,@RoleID,
@UserRoleNote)
l DeleteUserRole() 删除用户角色,调用存储过程DeleteUserRole
(@UserRoleID)
l GrantRolePermission(string RoleID string PermissionID string RolePermissionNote) 授予角色权限,调用存储过程GrantRolePermission(@RoleID,@PermissionID,@RolePermissionNote)
l DeleteRolePermission() 删除授予的角色权限,调用存储过程
DeleteRolePermission(@RolePermissionID)
4.2 用户认证代码设计(Client端)
Client端调用WebService方法来进行数据库访问,Client端代码设计主要实现界面的功能,包括:权限设置、用户管理、用户授权管理和用户认证管理
1)权限设置
class PermissionInfoMng() 用户权限信息管理类,包括方法:
l CreatePermissionInfo() 建立权限信息
2)用户管理
class UserInfoMng() 用户信息管理类,包括方法:
l CreateUserInfo() 建立用户信息
l ModifyUserInfo() 修改用户信息
l DeleteUserInfo() 删除用户信息
3)用户授权管理
class RoleInfoMng() 角色信息管理类,包括方法:
l CreateRoleInfo() 建立角色信息
l DeleteRoleInfo() 删除角色信息
class UserRoleMng() 用户角色管理类,包括方法:
l GrantUserRole() 授予用户角色
l DeleteUserRole() 删除用户角色
class RolePermissionMng() 角色权限管理类,包括方法
l GrantRolePermission() 授予角色权限
l DeleteRolePermission() 删除角色权限
4)用户认证管理
class Authentication() 用户认证类,包括方法:
l Login(string UserName string UserPwd) 用户登陆认证,用户认证通过分配给用户一个TicketID,否则TicketID则为null
l Logout() 用户正常退出
l ExceptionLogout() 用户异常退出
用户权限设计(一)——ASP.NET系统用户权限设计与实现【转】
分类: 软件技术 2006-11-21 09:59 2997人阅读 评论(0) 收藏 举报
引言
电子商务系统对安全问题有较高的要求,传统的访问控制方法DAC(Discretionary Access Control,自主访问控制模型)、MAC(Mandatory Access Control,强制访问控制模型)难以满足复杂的企业环境需求。因此,NIST(National Institute of Standards and Technology,美国国家标准化和技术委员会)于90年代初提出了基于角色的访问控制方法,实现了用户与访问权限的逻辑分离,更符合企业的用户、组织、数据和应用特征。ASP.NET是微软为了抗衡JSP而推出的新一代ASP(Active Server Pages)脚本语言,它借鉴了JSP的优点,同时它又具有自身的一些新特点。
本文将首先介绍ASP.NET的基本情况和RBAC(Role Based Access Control)的基本思想,在此基础上,给出电子商务系统中实现用户权限控制的一种具体方法。
ASP.NET概述
1、ASP.NET
ASP.NET是微软流行的动态WEB编程技术活动服务器网页(ASP)的最新版本,但它远不是传统ASP简单升级。ASP.NET和ASP的最大区别在于编程思维的转换,ASP.NET是真正的面向对象(Object-oriented),而不仅仅在于功能的增强。
在ASP.NET中,Web 窗体页由两部分组成:视觉元素(HTML、服务器控件和静态文本)和该页的编程逻辑。其中每一部分都存储在一个单独的文件中。可视元素在一个扩展名为 .aspx 文件中创建,而代码位于一个单独的类文件中,该文件称作代码隐藏类文件扩展名为.aspx.vb 或 .aspx.cs。这样,.aspx文件中存放所有要显示的元素,aspx.vb或.aspx.cs文件中存放逻辑。
2、用户控件(UserControl)
为了使用户能够根据需要方便地定义控件,ASP.NET引入了 Web 窗体用户控件的概念。实际上,只要将.aspx稍作修改即可转换为 Web 用户控件,扩展名为 .ascx,.ascx和.aspx文件一样也有一个存放逻辑的代码隐藏类文件,扩展名为.ascx.vb或.ascx.cs,只是它不能作为 Web 窗体页来运行,只有当被包含在 .aspx文件中时,用户控件才能工作。
通过以下两个步骤在WEB窗体页中设置用户控件:
(1)使用@ Register指令在.aspx文件中注册用户控件。如要注册在放在相对路径“../UserControl/”下的头文件headinner.ascx的方法为:
<%@ Register TagPrefix="Acme" TagName="Head" Src="../UserControl/headinner.ascx" %>
(2)在服务器控件的开始标记和结束标记之间(<form runat=server> </form>) 声明该用户控件元素。例如要声明上面所导入的控件的语法为:
<Acme: Head runat="server"/>
这样,该控件就成为页的一部分,并将在处理该页时呈现出来。并且,该控件的公共属性、事件和方法将向 Web 窗体页公开并且可以通过编程来使用。根据这个原理,就可以将每个页面初始化时所要执行的操作(如登录验证,角色验证)封装在用户控件当中。
RBAC的基本思想
RBAC(角色访问控制)的基本思想可简单地用图1来表示,即把整个访问控制过程分成两步:访问权限与角色相关联,角色再与用户关联,从而实现了用户与访问权限的逻辑分离。
由于RBAC实现了用户与访问权限的逻辑分离,因此它极大的方便了权限管理。例如,如果一个用户的职位发生变化,只要将用户当前的角色去掉,加入代表新职务或新任务的角色即可,角色/权限之间的变化比角色/用户关系之间的变化相对要慢得多,并且委派用户到角色不需要很多技术,可以由行政管理人员来执行,而配置权限到角色的工作比较复杂,需要一定的技术,可以由专门的技术人员来承担,但是不给他们委派用户的权限,这与现实中情况正好一致。
用户权限在.NET中的设计与实现
利用.NET中的用户控件实现权限控制的基本思想是:根据角色访问控制(RBAC)的基本原理,给用户分配一个角色,每个角色对应一些权限,然后利用ASP.NET中的用户控件(UserControl)来判断该用户对应的角色是否对访问页面有访问的权力。
下面将从数据库设计、添加角色和用户控件的使用等三方面来阐述具体实现过程。
1、数据库中表的设计
首先,在数据库中设计功能模块表、功能表和角色表等三个表。
(1) 功能模块表
为了管理好用户的权限,首先要组织好系统的模块,为此设计了一个功能模块表。见表1。
(2) 功能表
每个功能模块所具有的子功能称为功能,如商品管理模块goods(属于功能模块的范畴)包含商品信息查询、商品信息更新、商品信息删除、商品定价信息查询以及商品定价信息更新五种功能,功能表的设计见表2。
上面提到的例子可以作为这样几条记录分别插入功能模块表和功能表。
insert into TModule values(0,///////////////////////////////////////////////////////////////'商品管理模块///////////////////////////////////////////////////////////////',///////////////////////////////////////////////////////////////'goods///////////////////////////////////////////////////////////////',5);
insert into Tfunction values(0,///////////////////////////////////////////////////////////////'商品信息查询///////////////////////////////////////////////////////////////',///////////////////////////////////////////////////////////////'selectgoods///////////////////////////////////////////////////////////////',0);
insert into Tfunction values(1,///////////////////////////////////////////////////////////////'商品信息更新///////////////////////////////////////////////////////////////',///////////////////////////////////////////////////////////////'updategoods///////////////////////////////////////////////////////////////',0);
insert into Tfunction values(2,///////////////////////////////////////////////////////////////'商品信息删除///////////////////////////////////////////////////////////////',///////////////////////////////////////////////////////////////'deletegoods///////////////////////////////////////////////////////////////',0);
insert into Tfunction values(3,///////////////////////////////////////////////////////////////'商品定价信息查询///////////////////////////////////////////////////////////////',///////////////////////////////////////////////////////////////'selectgoodsprice///////////////////////////////////////////////////////////////',0);
insert into Tfunction values(4,///////////////////////////////////////////////////////////////'商品定价信息更新///////////////////////////////////////////////////////////////',///////////////////////////////////////////////////////////////'updategoodsprice///////////////////////////////////////////////////////////////',0);
(3) 角色表
角色表的设计关键在于角色值的定义,它是一个由0和1组成的类似二进制数的字符串。而功能表中的funcNo (功能编号)字段表示该功能在角色表的roleValue (角色值)字段中的位置,如果该位置对应的数值是0,表示该角色无此权限,如果值为1,则表示该角色拥有此权限。如角色普通会员的角色值为100100…00(共100位),如上所示,商品信息查询的功能编号为0,角色值100100…00的第0位为1,所以该普通会员角色拥有商品信息查询的功能;相反,该角色值的第1位为0,而功能编号为1 的功能为商品信息更新,所以该普通会员角色没有商品信息更新的权限。它们的关系可由图2来表示。
2、角色的添加
有了上面几个表,角色页面的功能模块以及其对应的功能都可以从功能模块表和功能表中读出,如图3所示。
在将新角色普通会员插入数据库时,先将角色值的所有位都置为0,然后利用.NET Framework 类库中的Replace函数将角色值中的打上勾的功能相应的功能编号位的值改为1。
例如,新添加一个角色名为普通会员的角色,它拥有的功能为商品信息查询(功能编号0)和商品定价信息查询(功能编号3)两项,则角色值应为1001000……00(100位),即角色值中第0位和第3位的值为1,其余为0。
3、利用用户控件实现访问权限
在定义好用户控件.ascx文件(head.ascx)及.ascx.cs(head.ascx,cs)文件时,接下去只要在.aspx文件中注册和声明它就可以了。
(1) 注册
<%@ Register TagPrefix="Acme" TagName="Head" Src="../UserControl/headinner.ascx" %>
(2) 声明
经过实践,在.aspx文件中声明.ascx文件可分为几种情况:
第一种情况:<Acme:Head runat="server" />
第二种情况:<Acme:Head runat="server" flag=0 funcname1=selectgoods funcname2=updategoods />
第三种情况:<Acme: Head runat="server" flag=1 funcname1= selectgoods funcname2=updategoods />
字段flag是用来控制怎样进行权限检查的标志,funcname指功能表中的功能英文名。如果flag为空,则不执行权限检查(第一种情况);否则如果flag=="0",则表示同时具有selectgoods(商品信息查询)和 updategoods(商品信息更新)这两种权限的角色所对应的用户才有权利查看该页(第二种情况);否则,如果flag=="1",则认为,具有selectgoods(商品信息查询)或 updategoods(商品信息更新)这两种权限中任意一种权限的用户就有权利查看该页(第三种情况)。
上面进行权限检查的过程全部由用户控件来实现,其全部方法都封装在.ascx.cs文件中,其中最主要的一个方法是检查某一角色是否拥有某一确定权限的checkAuth(string roleId,string funcEName)方法。这个方法的思想如图4所示。
图4中roleValue(角色值)的第0位(selectgoods的功能编号)值为1,表示该角色拥有selectgoods(商品信息查询)的权限。这样,我们把对权限检查的所有逻辑都封装在了用户控件中,因此,对WEB窗体页.aspx文件而言,只需在导入.ascx文件时确定用户在访问该页面时所应拥有的权限,而不需对aspx.cs进行任何改动。
由上所述,可以很清楚地看出,只要在用户控件中对用户权限进行控制,再把它包括在.aspx文件中(这件事作者本来就是要做的),那么在编程的时候就不必考虑复杂的权限问题了。
结束语
本文在开发一个电子商务系统的实践中发现,公司对系统用户的权限控制非常重视。因此,设计一个简单方便又行之有效的权限控制机制对于电子商务系统是必不可少的。本文所提出的基于ASP.NET的电子商务系统用户权限设计和实现方法已经在实际的工作中得到了验证,修改指定权限组的操作变得非常方便。下载本文