授权管理器访问组件
.NET Authorization using Windows Identity, X509 Certificate or ASP.NET Forms
引言
MSDN 发表了两篇关于使用授权管理器 (AzMan) 进行 .NET 授权的出色文章 ( Keith Brown, David McPherson ),这两篇文章都深入探讨了 AzMan 编程。但其中的代码示例不直接适用于开发者,他们更喜欢一个简单的 API 来执行 AzMan 授权,例如以下示例:
[AzManAuthorizaton("UseCase24", ClaimType = ClaimType.X509)]
public void MyMethod()
{
AzManAccessor.CheckPolicy();
.... // the rest of your business logic code
}
本文演示了如何设计和编码一个 AzMan 访问组件 ("AzManAccessor") 来实现这种简单性。此外,我还将 MSDN 关于 AzMan 编程的文章扩展到了使用 WSE 2.0 X509 证书和 ASP.NET Forms 票证进行授权,这是当今两个非常常见的 Web 场景。
AzMan Runtime API
可以通过 Windows 2003 Server 上的互操作程序集 C:\WINDOWS\Microsoft.NET\AuthMan Microsoft.Interop.Security.AzRoles.Dll 访问 AzMan Runtime(目前,AzMan 不适用于 Windows 2000 或 XP)。此 API 主要需要两个参数:操作名称和用户上下文。实际上,我们可以通过以下方式构建 AzMan Client Context:
IntPtr h=WindowsIdentity.GetCurrent().Token;
IAzClientContext ctx= app.InitializeClientContextFromToken((ulong)h,null);
或
IAzClientContext ctx= app.InitializeClientContextFromName(name,DomainName,null);
其中
name = HttpContext.Current.User.Identity.Name; // ASP.Net
// or
name = MapSoapContextToUser(RequestSoapContext.Current); //WSE 2.0
然后,我们可以使用 AzMan Client Context 进行“策略断言”
int oID = GetOperationID(attr.Operation, app);
object[] reusults = (object[]) ctx.AccessCheck(attr.Operation,null,
new object[1] {oID},null,null,null,null,null);
if ((int) results[0]!=0) { throw new Exception(...);}
其中 attr
是使用 StackFrame
对象构建的 AzManAuthorization Attribute。显然,我们通过属性和上下文类型传递了所有必需的数据(操作名称和上下文),这是 WS-* 消息导向世界中常见的现象。虽然 AzMan Runtime 现在可以对特定用户执行操作的访问权限检查,但我们尚未指定哪个用户有权访问哪个操作。这是 AzMan 管理 MMC 管理单元的工作,我们将在接下来进行介绍。
AzMan Admin Console
首先,AzMan 管理模型通过角色而不是用户来指定对操作的访问。换句话说,用户将通过属于某个角色来获得对操作的访问权限。其次,角色是通过 Windows 组(类似于 COM+)或 LDAP 查询(例如 title=Manager)来定义的,这两者都在用户上下文下的“查询”。现在,让我们看看本文如何构建 AzMan 存储。
- 策略文件位于 MyStore.xml 中,可以从授权管理器 MMC 管理单元加载。
- 已定义三个操作(Deposit、Auditing、MarketTiming)。
请注意,您需要切换到开发者模式才能看到操作列表。可以通过右键单击“授权管理器”节点 -> “选项”菜单项来完成此操作。每个操作都由其名称和操作 ID 定义。
- 已定义三个角色(Customers、Tellers、Partner)。
我们通过将操作添加到每个角色来定义它们。
具体来说,“Deposit”已添加到 Tellers,“Auditing”已添加到 Partners,“MarketTiming”已添加到 Customers。
- 本地“Guest”(已禁用)已分配给 Partners。“Administrators”组已分配给 Tellers,而 Customers 没有分配任何内容。
通过不向 Customers Role 添加任何用户,我们阻止了任何与 MarketTiming 相关的操作的执行。
我还假设您将以管理员身份运行演示代码“WinTest”,并以登录的 Administrator/xxxxxx 身份运行“WebFormTest”(基于表单的身份验证)。否则,您需要更改 AzMan 管理控制台中的角色分配,并更改 Web.config 文件中的 <authentication><credentials> 部分以使用新的组和新用户。
现在,我们已完成 AzMan 存储的设置,但需要正确安装演示代码才能看到 AzMan 的工作。
安装演示 .NET 解决方案
系统要求:演示代码必须在安装了 VS.NET 2003 和 WSE 2.0 的 Windows 2003 Server 下运行。
- 将下载的文件解压缩到 c:\AzManAccessor。
- 将 c:\AzManAccessor 共享为“AzManAccessor”到默认网站。
- 使用 IIS MMC 管理单元允许对“AzManAccessor”进行“匿名访问”。此步骤是为了允许 WSTest 运行,因为 WSE 2.0 不会传递调用者的 Windows 上下文,而是可以传递 SoapContext。此外,在 IIS MMS 管理单元中,将“WebFormTest”和“WSTest”设置为 Web 应用程序,方法是右键单击 -> 属性 -> 创建应用程序名称。
- 运行授权管理器 MMC 管理单元,加载 c:\AzManAccessor\MyStore.xml,并在“角色分配节点”下将“guest”分配给 Partner Role,同样将“Administrators”组分配给 Telles Role。
- 单击 c:\AzManAccessor\AzManAccessor.reg 以更新您的注册表。这将设置策略 URL 和默认应用程序以支持 AzManAccessor。
安装完成,您应该可以直接单击 .sln 文件来查看演示。
关于 X509 证书的说明
要运行此演示,需要在 Windows 2003 中安装证书服务器。我包含了一个由我的服务器颁发的证书,它肯定无法在您的服务器上工作,因为您的证书服务器或任何证书颁发机构都不会验证它。您应该使用您的证书服务器根证书覆盖此证书。您也可以从 VeriSign 请求试用证书并将其安装到您的证书存储中,如下所示,或者甚至将 test.crt 导入您自己的存储(警告:这对您来说存在安全风险,因为您信任了我颁发的证书)。
这是将 X509 证书加载到 WSE 2.0 客户端的代码。
X509CertificateStore store =
X509CertificateStore.CurrentUserStore X509CertificateStore.CAStore);
bool b = store.OpenRead();
X509Certificate cert = store.Certificates[0];
store.Close();
store =X509CertificateStore.LocalMachineStore(X509CertificateStore.MyStore);
b = store.OpenRead();
cert = store.Certificates[0];
store.Close();
请注意,我没有测试过在各种场景下使用 VeriSign 证书,例如未连接到 Internet 或安装到不同的存储区等。安装公用证书的方式太多了,我只能希望我的代码能在某些方面帮助您进行编码。
结论
我为您呈现了一个 AzMan 访问组件的非常简单的实现。我希望 AzManAccessor 能在处理您的实际问题时对您有所帮助,并与我们分享您的经验。