ASP.NET 2.0 中 AuthorizationStoreRoleProvider 可用性不高

一、授权管理概述

一般在应用程序中,比较理想、完整的授权模式就是基于角色的授权(Role Based Access Control-RBAC),它的主要目标是实现了用户与安全操作的分离,而在中间加入了角色的隔离层,从而实现了灵活性和可扩展性,具体来说,主要是这种方式:

  1. 在编写程序的时候,定义出程序的功能(或称为安全操作,如 AddBook, ModifyBook …)
  2. 在应用程序部署的时候,按照业务安全策略的要求,定义角色(如 BookManager),并定义角色与功能的对应关系
  3. 在应用程序运行期,定义可以使用系统的用户(如张三、李四),然后定义用户与角色的关系

这样通过“三个实体,两个对应”,就能找到用户和功能的关系(即用户能否执行此功能)。

二、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 之一,能为我们提供这些方面的便利功能,但在
使用之后才发现,限制依然存在,实用性仍然不够:

  1. 在定义角色时,它会把角色定义在 AzMan的“角色分配”结点上,而不是“角色定义”结点上,有点奇怪
  2. 如果使用 AspNetSqlMembershipProvider ,那么在为用户分配角色时,就会引发“帐户名与安全标识间无任何映射完成”的错误,这可以看出来 AzMan 依然是使用 Windows 用户,这一个限制很是致命,也就是说
    AspNetSqlMembershipProvider 和 AuthorizationStoreRoleProvider 是不能共用的

如果能够把 AspNetSqlMembershipProvider 中用户的 MemberId (GUID类型,格式为“XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX”)转换成 SID (S-R-I-S-S)还有可能通过 AzMan API 来利用AzMan ,但这不是通过 AuthorizationStoreRoleProvider 来进行的,而且目前我也没有找到好的、能够双向转换的方法。

三、一种实用的授权管理机制设想

目前临时想到一种即能完整实现 RBAC,又能利用 RoleProvider 的解决办法是:

  1. 利用 AspNetSqlRoleProvider 来管理 Role、定义 Role 与AspNetSqlMembershipProvider 中用户之间的关系
  2. 新增一自定义XML文件,在其中定义任务/操作列表,在编写程序时,可以在类或方法的属性中指定操作名称
  3. 同时在上述XML文件中定义 Role 与操作的对应(包含)关系
  4. 在程序中利用公用程序来检查权限,这无需写死(Hard Code)任何东西,因为是直接从当前类/方法中取出操作名称,再直接获得当前用户名,再检查第 2、3步的XML 文件文件即可。

“ASP.NET 2.0 中 AuthorizationStoreRoleProvider 可用性不高”的2个回复

  1. AspNetSqlRoleProvider 和 AspNetSqlMembershipProvider 提供了用户和角色管理,并没有提供权限管理,我用安全应用程序块实现权限管理。

评论已关闭。