一、授权管理概述
一般在应用程序中,比较理想、完整的授权模式就是基于角色的授权(Role Based Access Control-RBAC),它的主要目标是实现了用户与安全操作的分离,而在中间加入了角色的隔离层,从而实现了灵活性和可扩展性,具体来说,主要是这种方式:
这样通过“三个实体,两个对应”,就能找到用户和功能的关系(即用户能否执行此功能)。
二、ASP.NET 2.0 中的授权管理功能
ASP.NET 2.0中,提供了三种授权管理的提供者,分别为:AspNetSqlRoleProvider、AuthorizationStoreRoleProvider、AspNetWindowsTokenRoleProvider。
默认 AspNetSqlRoleProvider 只能提供角色与用户的实体及其对应关系,缺乏功能层次的定义和关系,所以仅能适用于有限场合,如基于 URL 的授权,或者在程序中手动使用 Roles API(Roles.IsUserInRole)来判断当前用户是否具有授权,但是这种方式的前提是角色是 Hard Code(硬编码的),以后如果角色所允许的功能发生了变化,只能通过修改程序来实现。
再来看看 Windows 2003 中附带的授权管理器(Authorization Manager,以下简称 AzMan),不可否认,它的设计比较完整地体现了 RBAC的思想,即首先定义操作,然后把操作归类形成任务(大任务也可以包括子任务),可以定义角色,然后在角色中定义其可以执行的任务或操作(大角色也可以包含小角色),最后可以应用程序中分配用户、建立角色与用户的对应关系,同时,AzMan 还提供业务规则检查的功能,即可以在任务级别定义脚本,对是否授权进行进一步的细粒度的检查,表面上看,还是比较圆满的。
但是 AzMan 的一个重大限制就是只支持 Windows 用户,它要求用户的标识为 SID(如S-1-5-21-XXXX-XXX)的格式。虽然我们可以使用 AzMan 的 API ,如 InitializeClientContextFromStringSid 来构造一个虚拟的 SID (例如,在我们的应用程序中,我们用户的 ID 为一个自增量的整数 Y,那就可以虚拟成 S-1-5-21-Y的方式)这样我们就可以利用 AzMan API 来绕开只允许Windows 用户的限制,但这些工作全部要手工完成,纯体力活,得不偿失。
本来以为 ASP.NET 2.0 的AuthorizationStoreRoleProvider 做为默认的三种 RoleProvider 之一,能为我们提供这些方面的便利功能,但在
使用之后才发现,限制依然存在,实用性仍然不够:
如果能够把 AspNetSqlMembershipProvider 中用户的 MemberId (GUID类型,格式为“XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX”)转换成 SID (S-R-I-S-S)还有可能通过 AzMan API 来利用AzMan ,但这不是通过 AuthorizationStoreRoleProvider 来进行的,而且目前我也没有找到好的、能够双向转换的方法。
三、一种实用的授权管理机制设想
目前临时想到一种即能完整实现 RBAC,又能利用 RoleProvider 的解决办法是: