利用 AOP 实现 .NET 上完整的基于角色的访问控制(RBAC)模型

近期帮别人在 ASP.NET 中实现简捷的安全/权限控制,于是进行了相关研究与内容搜集,并整理成代码,已在实际的项目中运用,效果突出,比 .NET 中的代码访问安全性(CAS)和 ASP.NET 中的相关安全控制机制更为灵活。

于是把其中实现的内容和主要代码共享出来,但内容较多,放在在随笔里会干扰大家查看首页的视线,所以归到文章里,感兴趣者可以在这里http://blog.joycode.com/moslem/articles/85194.aspx)查看。

本文及其中的代码主要介绍了以下内容:

  • 如何在 C# 中简捷/方便地进行 AOP 编程
  • 如何利用 AOP 来透明地在业务逻辑对象中进行权限检查
  • 如何实现完整的基于角色的访问控制模型
  • 如何在UI上针对不同的用户权限对控件进行设置(如禁止或隐藏)
  • 如何设置 Attribute,如何利用反射获取程序集中所有的、指定类型的 Attribute 定义
  • 其他相关内容

网上银行安全事件的反思

今年以来,网上银行安全事件层出不群,闹得沸沸扬扬,据网易财经:网银危机(http://finance.163.com/special/002521GA/ebank.html)上公布的信息,受害者近千人,损失资金金额也近千万元。

如果你在银行的科技部门,就知道这些事件带来的波动效应有多大,几乎所有银行的网上银行都极大的关注这些案件,从上至下,进行安全自查,封闭可能漏洞,关闭风险等级较高的功能,以最大限度地提高系统的安全性,降低客户的资金风险,当然,我也被折腾的够呛。可以说,工行此次事件不但给工行的声誉和上市进程造成了严重影响,而且几乎给所有其它银行的电子银行业务都带来很大的冲击和负面影响,我身边的好多人在了解到这些情况后,有的直接关闭了网上银行的功能,有的则坚定了不相信网上银行系统安全、而且决不开通网上银行功能的想法。

就整个事件反思,个人认为:

1) 工行的对整个事件的态度确实存在问题

在网上银行出了安全事件后,不分青红皂白,一律推到受害人身上,按“工行网银受害者联盟”(www.ak.cn)网站上事件相关人的描述,工行把受害人“妖魔化为弱智群体,然后把我们一脚踢到公安机关;甚至工行还混淆其商业银行的企业身份,对我们肆意诬蔑和打压”。

可以说,工行的这种态度是很多大型国有企业(包括其他行业)的通病,丝毫不出人意外,大家在日常生活中碰到这样的店大欺店案例并不鲜见。在最新一期的《新金融》杂志上,仍看见工商银行电子银行部的主管领导在推脱责任,说问题全出在用户身上。

个人对此也深有感触,有一位同学在工行数据中心,我们在聊起此事时,他仍坚称:整个事件仍是“别有用心”的人在夸大其辞,即使其中真有受害人,那也是他自己太笨。个人以为目前在中国,没有人敢公开地对中国工商银行这样的大目标“别有用心”,所以我宁愿相信,www.ak.cn 上公布的受害人,不存在造假的可能。

态度决定一切,国家足球队原主主教练米卢这话说得没错,我相信,如果工行不是始终独善其身、推脱责任的态度,事件也不会闹到如此地步。

回过头来看看招行,能够在网站上开通论坛,专门收集网友的反馈,来不断地更改和升级系统,印证了其“因您而变”的企业口号,其他哪家银行能有些魄力开这样一个论坛? 当然了,以现在这种系统的水平,最好还是不要开,会被口水淹没的。

2) 工行的系统确实存在问题

据我个人估计,这次大面积暴发的网上银行安全事件的主要原因就是出在工商银行网上银行系统登录页面的安全控件上,工行最早的网上银行系统使用的是普通的 HTML 控件,而且也没有使用验证码,后来,在系统升级时,加入了图片验证码,也加入了安全控件,但这个所谓“安全控件”的安全性并不高,不但不能防止大部分键盘记录软件(KeyLogger)的截获,也没有对数据进行加密(详见于2004年我对此进行的分析:网上银行“安全登录控件”分析),再后来,他们再次对安全控件进行了升级,对数据进行了加密,也能够防止大部分 KeyLogger 的截获,但据了解内情的人员透露,仍然存在漏洞,工行也在考虑进行进一步的升级。

有人也许会说,工行的系统管不了用户机器上的木马,但是,系统安全是一个整体的概念(信息安全领域的“木桶理论”),光做到银行端的安全是没有用的,黑客不会找最安全的地方来进攻的,即然网上银行系统的页面扩展到了用户端,那么银行就有责任地保护这部分应用(最薄弱的部分)的安全。

3)工行的安全事件响应机制存在问题

按照中国人民银行和银监会(它们在此次事件中也有监管缺失的问题)有关要求,商业银行在开办网上银行时,一定要建立安全事件响应机制。但就此次事件来看,没看出来他们的响应机制在哪里,首先是没有积极地帮助受害人锁定帐户,其次是没有积极与公安机关配合,尽早对所有事件统一分析,统一处理,而只是在事件闹得沸沸扬扬的时候,才“正面回应”,结果仍是“工行回应网银资金失窃案 称系统不存在漏洞”(http://news.tom.com/2006-08-18/000N/78413992.html)。

按说对于网上银行这种安全性要求非常高的系统来说,系统务必要记录访问客户端的所有细节,不但应包括最重要的客户端 IP 地址,还应该包括 HTTP 请求(Request)中的所有变量,如远程主机名、User_Agent、HTTP_REFERER、Accept-Language/Encoding等数据,这些数据将对追踪访问人、电子取证、案例侦破提供提供非常有力的证据,很多系统会记录 IP 地址,但往往会忽视其它一些特征数据的记录,而通过对这些数据的分析,有助于对那些通过代理来进行犯罪的黑客进行证据搜集。据个人分析,这些重要数据很可能被工行的网上银行系统所忽视,以至于影响了有效的响应过程。

其次,以工行的这样的大型企业来说,在事件发生时,完全有能力直接与最高级别的公安机关对话,对整个事件统一立案,集中力量统一侦破,相信很快会有结果,但是据了解,工行直到最近才把这事做起来,但这里,大好的时机都错过了。

4)客户所承担的安全成本太高

这不仅是工行的问题,几乎其他所有银行的网上银行系统都存在此问题,个人以为,在 USB-Key(工行称之为 U 盾)上赚客户的钱,纯属利令智昏之举,有的银行甚至以此来做为利润科目,实在是一大耻辱,这就和CCTV以送台大熊猫起名的时机敛财、欺骗全国人民感情的恶举如出一辙(年初起的名,现在还没有送过去),自己图名利,别人来买单。

既然是你系统提供的安全认证手段,费用就应该你自己负责,如果 USB-Key 收费,那是不是设置帐户/卡的口令也要收费? 即使收费,收点成本成不? 现在 1G 的U盘才多少钱,你那个 USB-Key 要收近百元?

除此之外,包括工行在内的多家银行收取所谓的“网上银行年费”,说的不客气,纯属脑子进水,想不明白确定收费的这些决策人员到底有没有了解网上银行业务对于网点/柜台减负所带来的成本节约?

我相信,USB-Key 的代价较高是绝大多数用户没有选择它的原因所在,工行现在推动态口令卡,依我看没必要,把 USB-Key 取消/少量收费即可。

还有一些小细节:大家现在访问一下工行网上银行系统,在登录页面上,仍然没有一些醒目的安全提示,登录页面那么大,就容不下一段关于防止身份盗用的说明? 看看页面源码,很多数据检查/校验的机制仍光溜溜地用 JavaScript 显示在那里,在看看进入系统时的这个地址:http://www.icbc.com.cn/wangyin_xitong/alert.jsp(网银_系统),不能起一个好一点、专业一点的目录名吗?(此网站上诸多目录都是以中文拼音命名)

=========================================================

回顾这个尚未结束的事件,可以认为它是对工商银行在网上银行系统安全保护不够完善的一个教训,也是对其他银行的一个警示,未尝不是坏事,亡羊补牢未晚也。当然了,要说推脱,工行还是有些理由的,毕竟它的网银用户数量在国内是最大的,因此黑客会选择攻击它的用户(这和微软的软件最常被攻击的原因类似),但是,只要扎扎实实地、全面地、负责任地做好安全工作,不要老喊口号而未真正地付诸行动,相信前景还是美好的,网上银行业发展的大潮仍是浩浩荡荡不可挡。

个人以此事件为启发,就网上银行系统的安全性来说,提出一些以后需要关注的问题:

1)降低客户所承担的安全成本,如 USB-Key 费用的降低,大力推广数字证书的应用;

2)学习招商银行(这似乎让很多大银行很没有面子),发展基于浏览器的专用客户端,不但功能更为强大、操作更为快捷方便,而且能够有效避免假网站、木马型病毒的攻击。我们看看欧美地区,大多数的较大的银行都支持OFX(开放金融协议),通过 Microsoft Money 等专用客户端可以直接连接到它们的系统中,个人认为这也是国内网上银行系统的发展方向;

3)改变目前系统中这种通过用户+密码的传统认证方式,只要使用用户名/密码,就有可能受到键盘记录木马的威胁,要彻底的解决此问题,必须
使用全新的身份鉴别技术。例如在 .NET Framework 3.0 中新推出的 CardSpace 技术(内置在 Windows Vista 中,可以安装在 Windows XP 上),就可以彻底地避免键盘记录软件、通讯侦听软件对身份鉴别过程的威胁;

4)进一步加强应用的安全性,在事前、事中、事后各个环节提高可控性,例如:可疑交易的确认(类似于信用卡的可疑消费确认),用户可自行设置登录时段、登录位置(如只限于北京地区)、进行风险等级较高的操作时,能够及时发送短消息通知用户,能够快速定位交易对手(转出时的目标帐户)的相关信息,能够快速锁定可疑账户,能够更完全面的记录客户端的信息,能够进行行为分析;

5)继续有策略、有技巧、持之以恒地加强用户安全教育,这在目前中国的互联网界流氓软件满天飞、普通用户极端受害的情况下,是非常非常有必要的。

一组 ASP.NET 2.0 主题文件下载

在 ASP.NET 2.0 中,大多数控件都可以直接“自动套用格式”,以便设置一些内置的配色方案,能够方便地设计多姿多彩、色彩丰富的页面,除些之外,ASP.NET 2.0 还提供了网站和页面的主题(Theme)和Skin的功能,可以在网页或网站层次设定各种控件的显示风格,以便统一站点的外观。

在实际开发中,实际上大家可能不会过多地采用内置的“自动套用格式”的功能,而是自己来设定控件的色彩、字体等,当然也有可能是通过 Theme/Skin 来进行的,但是,以我的实践来看,实现机制是很好,但结果往往另人不满意,主要原因是缺乏色彩方面的感觉,往往会设计出来色彩冲突、不协调,甚至在很多情况下相当不好看的界面 …

即然有这么好的实现机制,肯定会有人实现/共享很好的 Theme/Skin ,Google 了一下,找到一组 Theme,看起来还是相当不错的,可以直接应用的项目开发中,当然了,这组 Theme 也有一些小瑕疵,即某些对比色的过于接近而比较模糊。

 Theme预览:http://www.dotnettreats.com/SampleThemes/Default.aspx
 Theme下载:http://www.dotnettreats.com/tools/Default.aspx

在 ASP.NET 上实现锁定表头、支持滚动的表格的做法

首先看看 CodeProject 上的两个东西

1、The Freeze Pane DataGridhttp://www.codeproject.com/aspnet/FreezePaneDatagrid.asp

利用文章中提到做法及代码,可以实现在 ASP.NET 1.1 上的、支持横向滚动与纵向滚动的表格,基本上是使用 CSS 实现的,比较简单。

在 ASP.NET 2.0 上,由于文档 HTML DOCKTYPE 发生了变化(HTML->XHTML),所以在使用原文中的横向滚动条会出现问题,但是使用纵向滚动条和锁定表头没有问题。

这种做法没有考虑页面 PostBack 时记录表格的滚动位置,使得用户不得不重新去寻找刚才选中/编辑的那条记录,这比较的不人性化。

2、ScrollingGrid: A cross-browser freeze-header two-way scrolling DataGridhttp://www.codeproject.com/aspnet/ScrollingGrid.asp

此文章利用 Panel 控件和 DataGrid 控件实现了 ASP.NET 1.1 下的完整的、可实现双向滚动、表头锁定的表格,而且它实现了可以记录表格的滚动位置,页面 PostBack 后,表格仍能自动滚动到原有位置。这个控件的一个最大优点是能够适应多种浏览器,如 Internet Explorer 、FireFox 等。

在 ASP.NET 平台上,由于 DataGrid 控件已经升级为 GridView ,所以此控件已不能使用,按照文章下面的讨论,作者声称会尽快升级控件,但似乎在实现时碰到一些麻烦(如何确实表头各列的宽度),目前还没有结果。

目前我的做法:

  1. 参照文章1中提到的作法,利用 CSS 来实现锁定表头的功能
  2. 利用 Panel 控件,设置 ScrollBar 为 Vertical,再在其中放入 GridView 控件 ,可以实现竖向滚动条的功能
  3. 利用 Atlas ,将上述 Panel 再放入 UpdatePanel ,以透明实现保持滚动条位置的功能

示例代码:

<h1>滚动条表格演示h1> <style type="text/css">...... th {...}{...}{...}{ border-right: 1px solid silver; position:relative; top: expression(this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.scrollTop-2); /**//**//**//*IE5+ only*/ } style> <atlas:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="True"> atlas:ScriptManager> <br /> <asp:Panel ID="GridPanel" runat="server" Height="250px" ScrollBars="Auto" Width="562px"> <atlas:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1" SkinID="GridView" Width="434px"> </asp:GridView> </ContentTemplate> </atlas:UpdatePanel> </asp:Panel>

这样能基本上实现一个能够锁定表头、竖向滚动、能够在页面PostBack时保持滚动位置的表格,能够满足大部分应用需要。

几种常见的 ASP.NET 平台上表格控件的简单评价

由于这次试用它们的目的主要是寻找一种能够简单实现滚动条的表格控件,所以关注重点也在这个方面,其他方面没有过多涉及。

1. Developer Express ASPxGrid

  1) 程序本身有 Bug ,有乱码现象
  2) 代码量很大
  3) 不能创建 DataSource ,但可以绑定已经建好的 DataSource
  4) Scroll 动作需要 Postback 到服务器上,较慢,横向的无须 CallBack
  5) 代码量较大,尤其是处理数据更新时(例子有 600 行代码)
  6) 不支持自动格式,在 UI 定制方面工作量较大
  7) 过于臃肿,更象是一个 WinForm 而非 WebForm 的控件

  价格: 1 Developer License  $265
  网站: www.devexpress.com

2. ComponetOne WebGrid

   1) 和 GridView 比较接近
   2) 有专用界面来定义列
   3) 可以横向或纵向滚动,但要求将 Grid 的大小(宽度和高度)设置为绝对值,不能设为百分比
   4) 可以设置模板
   5) 必须设置列宽,不便于自动调整

   价格: $999.99  Componet Studio Enterprise
   网站: www.componentone.com

3. ComponentArt Grid

   1) 不带设计器,所有属性和事件都需要手动设置,无法在 GUI 下设计
   2) 大多数效果都是以代码实现的
   3) 启用滚动条的方式比较复杂,如需要设置 Scrollbar 的宽度,图像等

   价格: 1 Developer License 799$ (共 13 个控件)
   网站: www.componentart.com

4. Telerik Grid

   1) 内置 AJAX Framework,有可能和 Atlas 冲突
   2) 可以方便地设置 Scroll
   3) 支持的绑定控件比较丰富,直接支持 普通/Button/Checkbox/DropDown/HyperLink 等
   4) 支持 Theme
   5) 与普通的 GridView 的对象模型不太一致,需要重新学习其使用方法

   价格: 1 Developer License $399 (17个控件)
   网站: http://www.telerik.com

———————————-

这次比较令人意外的是,ComponentArt 的 Grid 控件没有 DesignTime 的 UI 支持,远远不如 ASP.NET 的 GridView 使用起来方便。

IIS 7 in Vista RC1

在控制面板中启用 IIS 时,发现各项功能的控制粒度很细,打开首页,只显示这样一个图片,不过目前 IIS7 的管理工具似乎还没有包含在 Vista 中。

这几天领教了 Vista 中的 UAC 和 Internet Explorer Protocted Mode 的厉害,不过,我对一部分最终用户能不能很好地接受这个Fetature信心不足,尤其是开启/关闭 UAC 的时候,需要重启计算机。

在 Internet Explorer Protocted Mode 时使用极点五笔,一直报错,不让访问安装目录下的码表文件(注:只在 IE 中报错,在其他应用程序中则不受影响),不得已,只好设置 Protocted 为 Off,现在我还没有找到其他好的解决办法,在网上看到一些 Post ,好象其他的一些输入法也有类似问题。

TechED 2006 参会印象

1、看起来参会人员似乎和去年差不多,可房间却十分紧张,最后挤在四人间,而且距离会场较远,TechED 渐有成为唯一的微软年度盛会之势,PDC 已经两三年不见了;

2、有幸见到一位厉害人物,VB 产品组的总经理潘正磊,从 Access 1.0 做起一直到现在 14 年,参与主持开发的产品很多,虽然自己现在 VB6, VB.NET 基本上用的 少了,但受到其个人魅力吸引,两堂课都听了,很受感慨,要是在中国,能找到这样一位14年编写代码,做产品规划和管理,还能在课上大讲 Debug 技巧与 Tricks/Tips 的人吗,一行一行调试代码的人吗?

3、Vista/Longhorn Server 的远程显示协议(RDP) 到 V6.0 ,支持 Gateway ,更安全(类似于 Outlook 的 RPC Over HTTPS),支持NAP(网络访问保护),可以直接支持远程应用程序,这个特性很 Cool,不过似乎很象 Citrix 的东西;

4、SharePoint 中的工作流基于 WF(为什么不叫 WWF 了?这和WPF、WCF不匹配呀)真不错,Kaneboy 演示的例子也非常好,看来也是精心准备的,可惜 kaneboy 问的问题没太有把握,没敢举手,没有拿到礼物,回头买一本支持一下,自己翻译过书,也知道写书、翻译书挺累的,要尊重作者劳动和知识 产权,呵呵,顺便夸奖一下 Kaneboy 的美女同事 TingLi ,技术、演讲能力都不错,同 Team 的其他成员都不错。回头再做开发的时候,要好好考虑一下能不能用 Infopath + SPS 2007 搞定,这样能避免大量无聊的代码了,开发生产力第一;

5、最近是国内各大银行网上银行的多事之秋,传统的“用户名+密码”的安全弱点已无法承担此重任,使用数字证书也仍然在端点上存在一些问题,Vista 的 CardSpace(InfoCard)技术来得正是时候,不过我估计给银行的决策人员介绍是可以,要用的话,估计还得段时间,要使用它,还是需要一些魄力与技术洞察力的;

6、今年听了一些 MOM 的课,东西是好东西,可如何说服领导花钱购买这个东西,提高管理水平,这似乎是个问题;

7、今年的动手试验室不错,但时间还是感觉紧张,脚本也没有翻译成中文,绝大多数人都做不完,不过能开放16个小时也不错,晚饭后还做了两个 Biztalk 2006 的试验,可惜没有带大硬盘,把这些虚拟机和资料 Copy 回家自己慢慢看;

8、今年的赞助商似乎不如去年,缺少去年 AMD 的那种气势;

9、今年的 MVP 活动感觉不如往年,没有很好的机会聚在一起好好聊聊,缺乏交流致使大家都不怎么互相认识,感觉比较陌生,而且把自己喜欢的一张 MVP 海报拉在房间里了,依旧感谢 MVP Lead 为我们申请的门票;

10、日程安排得挺紧张,有点累,得好好休息一下了,刚好凑够10条,呵呵。

令人不解的 roles 属性

在 ASP.NET 2.0 的 Web.sitemap 文件中,siteMapNode 有个属性 roles ,乍一看,就象是设置此结点允许哪些角色可以访问/显示,如:

<siteMapNode url=”~/Admin/Default.aspx” title=”系统管理” description=”” roles=”Manager”> 好象就表示属于 Manager 角色的用户可以访问/显示。但我在使用的时候却发现,无论当前用户是否登录,是否属于 Manager 角色,这个菜单项都能正常显示,且能正常进入,那这个 roles 属性的意义到底在哪里呢?

 

后来查了一下才发现,要想达到我说的效果(即根据用户的角色自动显示/隐藏菜单项),必须进行如下两个步骤:

1) Web.Config 的 SiteMap 中启用安全修整,完成后如下所示:

<siteMap defaultProvider=”default”>
  <providers>
    <clear/>
    <add name=”default” type=”System.Web.XmlSiteMapProvider” siteMapFile=”web.sitemap” securityTrimmingEnabled=”true” />
  </providers>
</siteMap>

2)利用 Web.config 来实现文件或URL授权,即对 Admin 目录下的设置访问规则(可以利用 VS 2005 中的 ASP.NET 配置来实现),完成后如下所示:

<system.web>
  <authorization>
    <allow roles=”Manager” />
    <deny users=”*” />
  </authorization>
</system.web>

现在菜单终于可以自动根据用户的角色是否属于 Manager 来显示/隐藏了,但问题是,这好象完全是 Web.config 来设置的,和 siteMapNode 中的 roles 一点关系也没有,那这么 roles 的意义在哪里呢?

从 MSDN 中找出这么一段话:“当用户属于 roles 属性中列出的某一角色时,使用该属性后,ASP.NET 可避开与 siteMapNode 关联的 URL 授权限制。”,可是如果我想避开限制的话,我就根本不用在 Web.config 中设置。既然在 Web.config 中设置了限制,却又在这里用 roles 绕开限制,是不是吃饱没事干了?

现在唯一能为这个 roles 找到一个很小的用处就是,如果结点上不指定 url 属性,可以利用此属性(roles=”*”)来强制显示此结点,以便能够显示下一级结点,如:

<siteMapNode url=”” title=”系统管理” description=”” roles=”*”>
    <siteMapNode url=”~/Admin/Member_List.aspx” title=”用户管理” description=””/>
    <siteMapNode url=”~/Admin/Role_List.aspx” title=”角色配置” description=”” />
</siteMapNode>

由于 url 没有值,所以只要 Admin 目录下利用 web.config 设置了授权规则,安全调整在检查时会隐藏“系统管理”这个结点,但设置了 roles=”*” 后,可以强制显示此结点,这样下面的两个子结点(菜单项)也能正常根据角色来显示。但是,这个理由也不充分,因为将 url 设置成 “~/Admin” ,也能达到上述效果。

那么,siteMapNode 结点中的这个 roles 属性的作用到底在哪里呢?

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 文件文件即可。