目录
基于角色的授权
ASP.NET 角色提供程序
自定义主 体
集中化授权逻辑
基于声明的授权
声明
声明集
授权上下文t
声明转换
安全令牌服务
当分布式应 用程序开始采用面向服务这一主体时,安全性挑战将变得略有不同。您会突然意 识到所调用的每个服务都将跨越安全边界。
虽然并不绝对必要,但通常 情况下服务调用的发送方和接收方之间应该存在网络。尽管通常情况下通信框架 会自动处理身份验证,但您仍需要建立自己的授权策略和基础结构。
Windows Communication Foundation (WCF) 能够为实现服务授权提供强 大的工具。您可以选择易于使用、基于角色的系统,或者更为强大但相对更为复 杂、基于声明的 API。本文的其余部分将比较这两种系统,并介绍如何使用它们 实现可靠的服务授权。
基于角色的授权
基于角色授权的基本原理 是为用户分配一组角色。在运行时,服务代码查询相关列表以做出与安全相关的 决策。这些角色既可以来自 Windows 安全系统(也称为组),或者也可以来自 一些自定义存储,例如数据库。
Microsoft .NET Framework 中的角色 API 基于名为 IIdentity(标识信息)和 IPrincipal(角色信息)的两个接口 。IIdentity 派生类包含诸如用户名、该用户是否经过验证以及验证方式之类的 信息。
IPrincipal 派生类必须实现一个名为 IsInRole 的方法,您可以 传入角色名并获得布尔型响应。此外,主体还包含对它所封装的标识类的引用。
.NET Framework 附带几个此类接口的实现。WindowsIdentity 和 WindowsPrincipal 封装了有关 Windows 用户的详细信息。GenericIdentity 和 GenericPrincipal 可用于代表经过验证的自定义用户。
此外它还包含用 于存储主体的位置,以便将其与应用程序中当前执行的线程(例如,WCF 操作请 求)相关联。该存储位置即是 System.Threading.Thread 类中的 CurrentPrincipal 线程静态属性。典型事件过程是应用程序的一部分填充 Thread.CurrentPrincipal,以便另一部分能够访问该属性以获取其中存储的 IPrincipal 实现。随后可以对该类调用 IsInRole 方法查询当前用户的角色列 表,以便确保调用程序已经授权能够执行该操作。
这正是它在 WCF 中的 工作方式。根据已配置的验证和凭据类型,WCF 可以创建相应的 IIdentity 实 现(WindowsIdentity 用于 Windows 验证,GenericIdentity 用于大多数其他 情况)。然后,根据 WCF 服务行为 (ServiceAuthorization) 的配置创建封装 该标识并提供角色信息的 IPrincipal 实现。然后在 Thread.CurrentPrincipal 中设置该 IPrincipalset,以便服务操作可以访问到它。
除编程调用 IsInRole 执行基于角色的安全检查外,还存在名为 PrincipalPermissionAttribute 的属性,可以通过它使用角色要求注释服 务操作。PrincipalPermissionAttribute 将通过在执行服务操作之前抛出 SecurityException 通知客户端授权失败。WCF 将捕获该异常,并将其转换成返 回的“拒绝访问”失败消息。WCF 客户端管道将会把该特殊失败消息 转换为 .NET 异常类型 SecurityAccessDeniedException。图 1 显示进行角色 检查和执行错误处理的各种方法。