使用 Authorization Manager 对多层应用程序进行基于角色的访问控制

来源:互联网 发布:2016国际金价数据 编辑:程序博客网 时间:2024/06/05 06:38

使用 Authorization Manager 对多层应用程序进行基于角色的访问控制

作者:Dave McPherson(Microsoft Corporation)

致谢:非常感谢 Jason Rush、Praerit Garg、Don Schmidt、Paul Leach 和 Doug Bayer 的支持。

*
本页内容
介绍介绍
授权策略存储授权策略存储
应用程序管理应用程序管理
审核审核
应用程序设计过程应用程序设计过程
开发 Authorization Manager 应用程序开发 Authorization Manager 应用程序
性能性能
特定于环境的设计事项特定于环境的设计事项
Internet Information Services 6.0 URL 授权Internet Information Services 6.0 URL 授权
场景:Web 开支应用程序场景:Web 开支应用程序
场景:使用带有自定义主体的授权管理器场景:使用带有自定义主体的授权管理器

介绍

在 Windows Server 2003 家族中,Authorization Manager(授权管理器)为 Windows 平台中的应用程序授权引入了一种新的模型。Authorization Manager 为业务应用程序提供了一种易用的授权框架,在这种框架中,您必须根据用户在组织或应用程序中的角色授予用户访问权限。为了达到这种要求,应用程序常常创建授权机制的自定义实现,这增加了开发成本和管理复杂性,因为存在着不同的授权模型。Authorization Manager 给应用程序提供了基于角色的访问控制,这使得管理更加容易而基于 Web 的应用程序或业务应用程序的开发更加自然。

ACL 和业务应用程序

由于在 Microsoft Windows NT Server 4.0 中引入了 Private Object Security API,所以 Windows 操作系统已经支持在应用程序的访问控制中使用 ACL。在 ACL 模型中,您可以将任意访问控制列表(DACL)附加到可保安全的对象中,并可以通过调用 AccessCheck 应用程序编程接口(API)来作出访问决定,该接口查看令牌中的用户组成员资格并且将它们与 ACL 的内容进行比较,以决定用户是否具有请求的访问权限。ACL 模型对于许多类型的应用程序都是非常理想的。定义明确的持久性对象的资源管理器(如:NT 系统注册表)可以适当地使用 ACL 模型来提供对象级访问控制。在这些类型的应用程序中,始终可以根据用户对现有系统的访问请求来作出访问控制决定。将来,使用 ACL 模型的应用程序应该使用 AuthzAPI,AuthzAPI 是在 Windows XP 和 Windows Server 2003 家族中引入的。它提供了性能和灵活性增强(与 Windows NT Private Object Security API 相比)。要获得更多关于 AuthzAPI 的信息,请参见 Microsoft Platform Software Development Kit(Microsoft 平台软件开发工具包)。

一些业务(LOB)应用程序中存在着完全不同的授权问题,比如:Web 开支报告应用程序或购物应用程序。对于这些应用程序,授权决定并不确定对定义明确的持久性对象的访问。相反,它们验证工作流或执行多个不同的操作,比如查询数据库和发送邮件。在 LOB 应用程序中,访问决策常常是根据业务逻辑作出的,比如在开支应用程序中提交的数量或工作流完成的验证,而不只是基于令牌组成员资格。不包含定义明确的持久性对象的应用程序没有空间来存放 ACL,因此 ACL 模型可能难于应用于这些应用程序。

基于角色的访问控制

传统的访问控制管理模型是基于对象的。在这些模型中,访问控制是在对象或对象容器中指定的(例如:在 ACL 中),而管理员必须到对象中查询和指定对对象的访问。这些模型需要管理员将组织授权策略转换成对象上的权限:每个对象都有授予组织中不同的用户和组的访问权限列表。基于角色的访问控制(RBAC)简化了访问控制管理,并且允许根据用户工作角色来管理权限,从而在组织中提供了更好的可管理性。

可以通过使用组来实现一些基于角色的访问控制的目的。一个组对应着一个雇员角色,而应用程序管理员可以通过授予在对象的 DACL 中授予组权限来指定角色所需要的权限。随着对象集合的不断增加,管理员需要管理的地方的数量也在不断地增加。连续使用资源组和用户组可以帮助将其工作量减少到最低限度,但是这需要不断的实践和管理员之间的协调配合以及资源组的精确定义。这些过程都会减慢管理进程,因此管理员常常避免使用它们。

加之,随着对象的数量的增加,跨应用程序查询授予特定组或角色的访问权限会变得越来越困难。为了精确地确定给用户或组授予了何种权限,管理员必须检查每一个对象上的权限。虽然继承功能看起来简化了这方面的工作,但是每个对象都避免继承权限的能力仍使得有必要查看每个对象,以完全理解授权策略。由于有太多的对象需要查询,所以有时就很少检验关于特定组或用户的访问控制状态。

基于角色的访问控制试图允许管理员根据公司的组织结构来指定访问控制。RBAC 通过创建称为角色(role)的新对象来达到此目的。您可以给用户分派执行某种工作职能的角色。然而,与组不同的是,角色将授权权限定义在资源的某些局部上。在 RBAC 模型中,管理员使用角色来管理权限和分派。例如,公司可能创建一个称为销售经理(Sales Manager)的角色,销售经理需要这个角色来满足他们的工作需要。当雇佣销售经理时,就给他们分派销售经理角色,而他们可以立即具有这份工作所需的全部权限。当他们离开销售经理的职位时,就会被从销售经理角色中删除,并且不再具有销售经理的访问权限。由于角色使得可以根据公司的组织模型来授予访问权限,所以对于管理员来说,指定访问控制更显得直观和自然。图 1 标识了角色、用户和权限之间的关系。在这个模型中,角色是授予权限的对象,而且给用户分派了角色。

图 1:基于角色的访问

图 1:基于角色的访问

RBAC 将用户的工作角色映射到应用程序权限,这样就可以根据用户工作角色来完成访问控制管理。RBAC 系统将用户角色成员资格转换成应用程序权限。由于权限是在角色上授予的,所以可以在角色上查询和更改权限,而无需检查特定的资源。在大多数环境中,一旦建立了角色权限,就很少会对角色权限进行更改(与角色分派中的更改相比)。这意味着管理员将必须设置角色,比如:雇员(Employee)、经理(Manager)和管理员(Administrator),但是一旦角色创建完毕,管理员就将管理角色中的成员而不是对象上的权限。

Authorization Manager 概念模型

Authorization Manager 是一组基于 COM 的运行时接口,允许应用程序轻松地管理和检验客户端请求,以便执行应用程序操作。另外,Authorization Manager 提供了 Microsoft Management Console(MMC)插件,应用程序管理员可以使用该插件来管理用户角色和权限。

Authorization Manager:

可以简化业务应用程序中的应用程序访问控制管理。

可以提供简洁而自然的开发模型。

可以启用灵活、动态的授权决策。

在一般情况下,您可使用术语主题(Subject)、资源(Resources)和权限(Permissions)来定义访问控制模型。主题常常是用户对资源进行的操作。访问是由一组权限控制的,这组权限允许主题对资源执行特定的操作。访问控制的管理很少直接处理这些构造,而更为常见的就是管理主题、资源和权限的集合。您通常在组中管理主题或用户,而在特定于应用程序的集合(比如:目录或组织单位)中管理资源。虽然可以直接授予权限,但是常常将权限分组到更高级别的权限,比如:完全控制(Full Control)。这些集合使得在有多个主题、资源或权限的环境中进行授权管理成为可能。应用程序管理员必须使用这些集合来制订应用程序的授权策略,这样每个主题就都有合适的权限来使用应用程序资源。

传统的资源管理器存储授权策略以及策略应用的资源。例如,文件中的 ACL 是由资源管理器存储的并且在逻辑上与该文件相关联。在 Authorization Manager 模型中,授权策略数据与授权策略存储中的对象是分开存储的。应用程序标识应用程序可以执行的操作或任务,并且在应用程序安装时在授权存储库中加以声明。管理员通过定义角色(根据执行组织中的某项工作所需要的任务和操作)来管理授权策略。定义角色、任务和操作以及给角色分派用户和组的信息都存储在授权存储库中。应用程序在运行时查询授权策略来确认已经授权客户端对资源执行所请求的操作。Authorization Manager 提供 API 来管理授权策略并检查管理员的访问控制和用户接口的有效性,这样他们就可以管理受权策略存储。下图展示了 Authorization Manager 为查询应用程序和管理授权存储库而提供的授权存储库的组合,并展示了每个 Authorization Manager 对象之间的关系。

图 2:Authorization Manager 中的对象关系

图 2:Authorization Manager 中的对象关系
查看全尺寸图片。

定义

这一部分介绍了 Authorization Manager 用来管理授权策略的对象。

操作(Operation):资源管理器使用低级权限来标识安全过程。可能需要几种操作来执行一项有意义的任务。对于管理员来说,操作常常是不公开的或没有意义的。操作范例可以是 WriteAttributes(写入属性)或 ReadAttributes(读取属性)。任务(Task):低级操作集合。任务用于确定需要哪些低级操作来完成对管理员有意义的某些工作单元。任务范例可能就是更改密码(Change Password)。任务还可以包含其他任务。例如,称为管理用户帐户(Manage User Accounts)的任务可以包括更改密码(Change Password)、重新设置密码(Reset Password)、禁用帐户(Disable Account)等任务。角色定义(Role Definitions):特定角色所需的权限的集合,其中,权限可以是任务,也可以是操作。注意,该定义类似于任务的定义。角色(Role):用户为完成他们的工作所必须具有的权限的集合。角色应用于一组对象,而用户分派给角色。BizRules,也称为授权脚本(Authorization Scripts):附加到任务对象的脚本,在访问请求时运行。它可以使用只是在运行时才可用的信息(比如:“当天时间”或“请求的美元数额”)来做出授权决策。作用域(Scope):使用完全不同的授权策略的对象或资源的集合。作用域可以代表物理集合(如:文件夹),也可以代表更复杂的资源集合(如:*.doc)。应用程序可以将作用域用作组资源必需的一部分,而且在应用程序检查用户的访问时必须能够将请求的资源映射到其作用域。应用程序组(Application groups):只可应用于授权存储库、授权存储库内的应用程序或应用程序内的作用域的组。Authorization Manager 实施两种类型的应用程序组。应用程序基本组(Application basic groups):属于应用程序组的一部分,为一组特定的应用程序、单个应用程序或应用程序内的作用域而维护的成员列表(Active Directory 用户或组或其他的应用程序组)。应用程序组还可以标识非成员,这是考虑到会出现一些异常的情况,比如一个大组可以与一个小一些的组或被排除在外的某个特殊的用户一起使用。LDAP 查询组(LDAP-query groups):属于应用程序组的一部分,由轻量级目录访问协议(Lightweight Directory Access Protocol,LDAP)在特定的 Active Directory 用户帐户属性中定义的组。可提供灵活的组成员资格,可根据用户帐户属性进行定义并对用户帐户对象保持更新。

返回页首返回页首

授权策略存储

当初始化使用 Authorization Manager 的应用程序时,它从存储库加载授权策略信息。Authorization Manager 为在 Active Directory 或 .xml 文件中存储授权策略提供支持。

重要须知:因为授权策略信息是由 Active Directory 存储的或存储在 NTFS 文件中,所以其通过 Active Directory 或 NTFS 的安全性功能加以保护,而直接对存储进行的更改的审核支持是由该存储库所在的系统进行处理。另外,包含授权策略存储库的系统中的管理员具有很高的访问存储库的权限。因此,授权策略存储必须位于受信任的系统中。

Active Directory Authorization Manager 存储

要使用 Active Directory 来存储 Authorization Manager 策略,该域就必须具有 Windows Server 2003 的功能级别。Windows Server 2003 家族中的 Active Directory 包含 Authorization Manager 对象的模式更新。当使用 Active Directory 存储时,Authorization Manager 为存储库本身和每个应用程序组、应用程序、操作、任务、角色和作用域创建 Active Directory 对象。作用域对象可以包含在该作用域中所创建的任务、角色和组。

当使用 Active Directory 授权策略存储库时,应用程序控制何时加载应用程序对象。当应用程序连接到策略存储库时,存储库全局属性(包括存储库级组在内)就与每个应用程序的报头信息一起进行本地缓冲。当应用程序使用 OpenApplication 方法来初始化其授权策略时,每个作用域的应用程序属性、角色、任务、操作、应用程序组和报头信息就都加载到内存中。一旦加载了应用程序,它就在内存中保持缓冲状态,直到应用程序对象被释放为止。作用域是按需加载的;或者是在第一次对 AccessCheck 的调用中指定作用域时,或者是在使用 OpenScope 方法显式加载作用域时。一旦加载了作用域,它就在内存中保持缓冲状态,直到应用程序对象被释放为止。

Active Directory 不支持在多个对象或属性中强制事务编写,因此由两个管理应用程序同时编辑存储库是可能的。在这种情况下,存储库可能会被破坏。正因如此,我们建议应用程序定期备份它们的授权存储库。如要获得更多关于 Active Directory 备份和恢复工具的信息,请参见 Windows Server 2003 帮助中的“Active Directory”。

Active Directory 管理员需要考虑的部署事项

应用程序管理员可以从使用 Active Directory 存储授权策略中受益。Active Directory 存储允许应用程序利用现有的域基础结构对应用程序提供存储、可用性、冗余度和授权策略的分布。部署 Authorization Manager 的 Active Directory 管理员应该考虑下列信息:

域模式要求

Authorization Manager Active Directory Store 要求域位于 Windows Server 2003 功能级别。

Authorization Manager Active Directory 对基础结构的影响

Authorization Manager 是运行在应用程序服务器中的运行时,不在域控制器中运行任何应用程序或服务。Active Directory 可以用于存储授权策略数据。

当初始化和下载所需的应用程序作用域策略时,使用该策略的应用程序下载应用程序策略信息。当应用程序读取该策略信息时,这种读取对域控制器的影响将会改变。应用程序或作用域的授权策略的大小将随着作用域中角色的数量、任务、操作和组的改变而改变。虽然应用程序组的大小可以改变,但是建议您不要将应用程序组用于大型组,以便应用程序的性能不受影响。尽管组和角色的大小可以改变,但是它可能与 Active Directory 组相类似。读取组或角色所耗费的处理时间与读取包含相同数量的成员的 Active Directory 组的成员所耗费的处理时间一样多。虽然应用程序组可以有与 Active Directory 组相同的最大容量,但是它通常比 Active Directory 组小一些,因为它们仅供应用程序使用。当需要包含 5000 个以上的成员的组时,如果可能的话,我们建议大家使用 Active Directory 组来代替应用程序组。

接近要求

应用程序需要对 Authorization Manager 策略进行高质量的访问。虽然在窄带场景中单个应用程序的执行可能是可接受的,但是除非它们具有小型授权存储库,否则域控制器通常还是应该位于应用程序服务器的局域网(LAN)中

复制

授权策略存储库被复制到存储授权策略的域的所有域控制器中,而且林中的每个全局目录服务器内都引用了 Authorization Manager 对象。

单独的域或林可以用于存储 Authorization Manager 策略。您可以选择这样做来将域内的复制流量降到最低,从而将帐户域内的域控制器上的负载降到最低,也可以选择让单独的管理员来管理 Authorization Manager 策略存储库。使用单独的域或林需要在存储用户帐户的域(帐户域)和存储 Authorization Manager 的域(Authorization Manager 存储域)之间建立正确的信任。需要的受信任配置取决于 Authorization Manager 策略的管理员的帐户在什么域中以及应用程序服务器和所有后端资源在哪个域中。

在 Active Directory 中部署 Authorization Manager 存储库

下面给出了关于在 Active Directory 中部署 Authorization Manager 存储库的循序渐进的指导。

1.

选择 Authorization Manager Active Directory 存储库的位置

要在 Active Directory 存储中部署 Authorization Manager,您必须选择存储库的位置。建议管理员在域的 Program Data 容器中创建一个新的组织单元(OU),并且在新的组织单元中创建一个存储库对象。这个建议不是强制性的。如果应用程序在除 Program Data 以外的容器中有数据,您就可以将 Authorization Manager 存储库放入其中。

Authorization Manager 不能放在非域命名上下文(也称为 应用程序分区)中。

2.

创建 Authorization Manager 存储库

应用程序可以通过 Authorization Manager API 在 Active Directory 本身中创建 Authorization Manager 策略存储库,而管理员也可以通过使用 Authorization Manager MMC 来创建存储库。为了达到此目的,尝试创建存储库的用户或应用程序必须在上一步选择的容器中拥有创建子对象(Create Child Object)权限,并且必须知道该容器的专有名称。

要了解更多关于使用 Authorization Manager MMC 插件创建存储库的信息,请参见 Authorization Manager 帮助中的“使用授权存储库”章节。

3.

角色和授权存储库访问

如果应用程序管理员使用程序创建存储库,那么他们就应该已经具有管理存储库的权限。如果存储库由 Active Directory 管理员手动进行创建,则管理该存储库的权限就必须赋予使用该存储库的应用程序管理员。可以使用 Authorization Manager MMC 来授予应用程序管理员访问权限,以便管理授权策略存储库。该存储库内的授权策略由应用程序管理员进行管理。Authorization Manager Active Directory 存储允许应用程序管理员委托应用程序的管理和存储库内的作用域。

由于使用授权策略的应用程序服务帐户必须能够读取策略存储库,所以应用程序服务帐户必须包括在读者(Reader)角色中,而读者角色可以属于适当的存储库或应用程序或存储库内的作用域。

4.

启用 Windows 授权访问组

注意:只有当应用程序设计人员使用 InitializeClientContextFromNameInitializeClientContextFromStringSID 方法创建应用程序内的客户端上下文对象时,才需要完成这一步。使用 InitializeClientContextFromToken 的应用程序则不需要这一步。如果您不敢肯定应用程序服务器将使用哪些 API,您可以向应用程序管理员或设计人员询问,他们应该会知道。

这些方法试图读取 Active Directory 中用户 token-groups-global-and-universal 属性,以便获取用户的 Active Directory 组成员资格信息。要读取这种信息,应用程序服务帐户必须具有对每个用户对象的该属性的读取(Read)权限。

如果该域是为“Windows 2000 以前版本的兼容访问模式”配置的(即“所有人”(Everyone)组在“Windows 2000 以前版本的兼容访问”组中),则在默认情况下,“经验证的用户”(Authenticated Users)组将有权调用 InitializeClientContextFromNameInitializeClientContextFromStringSID 方法。如果该域是针对 Windows 2000 和“Windows Server 2003 兼容访问”设置的,则在默认情况下,只有“经验证的用户”组在“Windows 2000 以前版本的兼容访问”组中。在这种情况下,应用程序服务帐户将具有调用 InitializeClientContextFromNameInitializeClientContextFromStringSID 方法所需的权限。如果该域已经被锁定(即 Active Directory 管理员更严格地限制了默认访问权限),则“Windows 2000 以前版本的兼容访问”就有可能为空,在这种情况下,服务器在调用 InitializeClientContextFromNameOfSID 接口时可能会失败。

如果出现这样的情形,为了授予服务帐户访问的权限,建议您首先将服务帐户添加到“Windows 授权访问”(Windows Authorization Access)组中,然后授予“Windows 授权访问”组访问每个用户 token-groups-global-and-universal 属性的权限(如果它还不具有这种访问权限的话)。如要了解更多关于“Windows 授权访问”组(属于 Windows Server 2003 家族中的一个新组),请在 Microsoft 知识库(http://support.microsoft.com/)中搜索该术语。

Authorization Manager 中的 XML 文件存储

Authorization Manager 支持通过 .xml 文件存储授权策略(即存储在 NTFS 卷中)。XML 存储库可以保存在与使用 Authorization Manager API 的服务器应用程序相同的计算机上,也可以进行远程保存。

为了支持对象的重命名,XML 格式包含全局惟一的标识符(GUID)。因此,您不应该直接编辑 .xml 文件。此外,XML 模式目前尚未发布。您可以通过 Authorization Manager MMC 来编辑存储库,也可以通过 Authorization Manager 接口来编辑存储库,Authorization Manager 接口可用于脚本语言,比如:Microsoft Visual Basic Scripting Edition(VBScript)和 JScript。XML 存储不支持委托,因为对 XML 文件的访问是由准许或限制访问该文件的整个内容的文件中的任意访问控制列表(DACL)控制的。

建议应用程序管理员定期备份他们的授权存储库。当多个应用程序都在写入同一个文件时,NTFS 文件系统并不支持它们将一系列的单独写入操作作为单个逻辑写入操作写入文件中。(这些操作有时称为事务操作。)由于 Authorization Manager 策略存储库可同时由两个管理应用程序进行编辑,所以存储库可能会被破坏。

返回页首返回页首

应用程序管理

在安装完应用程序之后,管理员的工作就是添加任何所需的新角色,检验初始角色上的权限(如果存在的话),并且给角色分派用户。如果应用程序创建了一组完整的具有有意义的名称的任务,则管理员设置初始角色的工作就要容易得多。

基于角色的访问控制的特点在于使管理更直观、更容易。要达到此目的,管理员就必须设计一个在应用程序中部署角色的策略,这类似于用户工作描述。一旦建立了角色,管理的重点主要就是管理角色内的成员资格,因此检验每个角色权限是非常重要的。一般来说,应该只授予每个角色立即需要的权限,然后在需要时再添加权限,而不要先授予太多的权限,然后再删除不需要的权限,前者更安全一些。

管理作用域

通常,由应用程序创建作用域,然后再由管理员在作用域内创建和管理角色。如果采用这种方法,管理员就不必知道用来使用户访问请求与作用域相关联的应用程序作用域语法和应用程序逻辑。

当应用程序允许管理员创建作用域时,应用程序就必须提供文档,只有这样,管理员才能理解如何创建正确命名的作用域,因为作用域是由每个应用程序定义的,并且应用程序将把每个访问请求映射到适当的作用域中。

作用域允许管理员将应用程序资源分成物理或逻辑集合,并且在每个作用域中指定不同的授权策略。由于可以创建任务和角色的定义,这样它们对于应用程序就是全局的(换句话说,在所有的作用域中都是可见的),所以为不同的作用域创建的角色可以使用相同的全局定义而具有不同的成员资格。这使得不需要在每个作用域中重新定义权限。如果角色或任务(比如:管理员或完全控制)在每个作用域中都将有相同的权限但是却会分派不同的人员,这种方法就非常有用。

重要须知:Authorization Manager 具有默认的作用域。在默认的作用域中授予角色的权限会应用于应用程序内的所有作用域。由于这个原因,所以只有应用于应用程序内的所有作用域的角色分派才应该使用应用程序默认作用域。

角色继承

由于建立角色的过程涉及分派用户权限,所以需要特别小心。为了将所需的验证和分析减少到最低限度,在创建新的角色时,可以设计继承角色模型来利用建立现有的角色所做的工作。

图 3:角色继承

图 3:角色继承
查看全尺寸图片。

角色定义涉及定义角色的权限的任务和操作。使用角色定义允许以继承的方式定义角色,也就是通过现有的角色来创建新的角色。

管理的委托

当使用 Active Directory Authorization Manager 策略存储库时,Authorization Manager 支持授权存储库、应用程序和作用域级的管理委托。这使得更高级别的管理员能够赋予其他管理某些部分的授权策略的管理员有限的访问权限。存储、应用程序或作用域的管理员可以执行管理委托的作用域内的授权策略所需的全部操作,而读者只能读取授权策略。另外,还必须将已经委托作用域或应用程序的授权的用户添加到存储的库委托用户(Delegated User)管理角色中。这允许用户查看在应用程序级和存储库级所创建的组。

在委托了作用域之后(因为有一个或多个主体位于作用域的管理角色中),就不能将 BizRules 添加到在作用域中所创建的任务或角色定义。委托作用域可以使用附加到应用程序级的任务和角色定义的 BizRules。存储库级管理员也可以通过将 ScriptEngineTimeout 的存储级的值设置为 0 来全局阻止 BizRules 的运行。这样做了之后,AccessCheck 就假定现有的 BizRules 将返回为 False,并且将不通过包含 BizRule 的任务或角色定义授予访问权限。

使用 Authorization Manager 应用程序组

Authorization Manager 引入了两种类型的组,应用程序基本组和 LDAP 查询组,Authorization Manager 可以使用这两个组来简化需要维护安全主体的组的应用程序。(在本文的后面我们将更详细地讨论这些方面。)对于 Authorization Manager 策略存储库,Authorization Manager 应用程序组可以是全局组,可特定于某个应用程序并且由该应用程序内的所有作用域使用的存储库,或者特定于单个应用程序的存储库中的任何应用程序都可以使用Authorization Manager 应用程序组。一些应用程序需要管理用户组而不必依赖于对域组的更新(这可能由不同的人进行管理)。域管理员可能需要保持较少组,而无需管理应用程序级的组。在应用程序员的请求和实际对 Active Directory 所作的更改之间可能会存在一定的延时。另外,一些组只是满足某些应用程序的需要,如果这些应用程序可以管理组成员资格,域管理员就不必涉入了。

应用程序基本组

应用程序基本组类似于传统的 Windows 域组,因为它是成员安全主体的集合,但又不同于传统的组,因为它包含安全主体的非成员列表或负列表,从而允许在对象中传统使用拒绝(Deny)访问控制条目(ACE)的异常。添加到非成员列表的安全主体决不会是组的成员,即使它们直接或间接地被授予了成员列表中的成员资格也是如此。应用程序基本组存储每个成员和非成员的安全标识符(SID),这样应用程序组就将随着 Authorization Manager 存储库的增加而增加。由于应用程序会将部分授权存储库库加载到内存中,因此大型组和角色的成员资格可能会增加初始化 Authorization Manager 存储库、应用程序或作用域对象所需的时间。

当应用程序组变得非常大时:

初始化存储、初始化应用程序和调用 AccessCheck 的性能都会受到影响。

需要在应用程序方面投入更多资金。

当应用程序初始化和刷新加载的策略时在域中存在更多的负载。

应用程序组中的成员资格常常变化,这需要更频繁地刷新缓存。

因此,我们强烈建议,当应用程序组发展到大约 2000 个成员时,应该将它们转换为 Active Directory 组。(要获得更多关于性能的信息,请参见本文后面的“性能”部分。)当用户登录时或系统创建用户上下文时,用户 Active Directory 组的成员资格就被确定了,并且不会影响初始化 Authorization Manager、应用程序或作用域所需的时间。

LDAP 查询组

通常,组是保留在 Active Directory 中的用户集合,这些用户的 Active Directory 帐户具有类似的属性。例如,在特定的成本中心工作的用户可能就在该成本中心的一个组中,即使成本中心信息是作为每个用户帐户的属性保存在 Active Directory 中也是如此。当用户从一个成本中心转移到另一个成本中心时,管理员必须更新两个成本中心组以及该用户对象的成本中心属性。为了能够利用用户属性,并使管理员不必将同样的信息放在多个位置上,Authorization Manager 提供了 LDAP 查询组。

LDAP 查询组中的成员是利用给定的用户对象中的 LDAP 查询来确定的。这就可以使应用程序将用户属性作为组在角色中加以运用,并免去管理员管理这些组的成员的麻烦。应用程序管理员可以根据用户帐户的特性,通过创建 LDAP 查询组来控制成员。以下是编写 LDAP 查询组的一些示例。

Managers 组的所有成员为:

(memberOf= CN=Managers,OU=Distribution Lists,DC=nwtraders,DC=com) 

所有 18 岁以上的成员。

(age>=18) 

所有德国用户

(country=Germany) 

所有 18 岁以上的德国用户

(&(age>=18)(country=Germany)) 

LDAP 查询组要求已连接的用户帐户保留在 Active Directory 中,但它们在使用基于 XML 的 Authorization Manager 策略存储库时也是受支持的。AccessCheck 在调用时会对 LDAP 查询组做出评估,因此,在角色中植入 LDAP 查询时,调用 AccessCheck 需要更多的时间,因为在评估查询时需要在 Active Directory 中执行 LDAP 搜索。当针对客户端上下文的生命缓冲 LDAP 查询组中的成员时,初始的 AccessCheck 调用都会比较慢,因为需要评估许多 LDAP 查询组。

企业范围内的角色

由于 Authorization Manager 角色是根据应用程序内角色需要的权限而定义,所以角色不能跨应用程序。为了使不同的应用程序中的角色具有相同的成员资格,可以使用公共组来植入应用程序角色。这可以运用 Windows 组来完成,如果应用程序是由同样的 Authorization Manager 策略存储库进行管理,也可以运用应用程序组来完成。这些组对每个应用程序来说都是可见的,并且包含在多个应用程序中定义的角色成员。因此,在每个应用程序中都可以将这些组作为角色的成员来分配。通过使用 Active Directory 全局或通用组来包含角色成员,一个组织中的应用程序角色就可以拥有跨应用程序和 Authorization Manager 策略存储库的类似成员资格。

返回页首返回页首

审核

Authorization Manager 提供了两类审核。

Authorization Manager 运行时审核

Authorization Manager 策略存储库变更审核

Authorization Manager 运行时审核

Authorization Manager 运行时审核审核以下内容:

应用程序初始化

客户端初始化或删除

所有审核通过和审核失败的 AccessCheck 调用

审核可以在存储库或应用程序级上加以配置。Authorization Manager 运行时审核可以通过 AzAuthorizationStore 接口的 GenerateAudits 特性予以启用,这类审核存储在 Authorization Manager 策略存储库中。

为了使用 Authorization Manager 运行时审核,运行 Authorization Manager 的系统必须启用审核,同时调用 Authorization Manager 接口的上下文必须具有 SE_AUDIT_NAME 或 Generate Audits 权限。如果一个应用程序需要启用审核,可以通过将 AZ_AZSTORE_FLAG_AUDIT_IS_CRITICAL 标志传递给 IAzAuthorizationStore::Initialize 而获得审核权限。这需要应用程序具有 SE_AUDIT_PRIVILEGE,否则 IAzAuthorizationStore::Initialize 会失败。

Authorization Manager 策略存储库变更审核

当 Authorization Manager 审核策略改变时,将触发 Authorization Manager 策略存储库变更审核。因为 Active Directory 支持 Active Directory 对象审核,所以可以运用 Active Directory 系统审核审核 Active Directory 存储库变更,其中可在存储、应用程序和作用域等级别上配置审核设置。可以运用对象上的系统访问控制列表(SACL),将 XML 存储库的变更作为一个整体进行审核。

返回页首返回页首

应用程序设计过程

选择好角色、任务和操作是应用程序设计的一部分。本部分将提供一些信息来帮助您设计应用程序。

确定操作

操作是一个低级权限,表示应用程序的特权操作或能力。必须为每个包含需要访问控制的单个应用程序功能的例程、查询、方法等创建操作。单一操作并不足以执行一项高级任务,可能需要更多的高级任务,但操作本身总是作为一个单元执行,而且必须受到保护。

举个例子来说,一个操作本身(例如 ReadOrderInfo)并不足以执行高级任务 Process Order,而另一个高级任务(如:Query Order Status)可能需要同样的例程。为需要的例程组创建一个操作以便使用命令控制可以为更好的权限规范创造条件。操作定义得越精确,管理权限的灵活性就越高。然而,操作定义得太精确,管理就会更加复杂。

对于许多资源管理器,操作对应于可保安全的例程、程序或处理数据或资源的查询。操作可能是低级的,只对应用程序开发人员有意义。为了创建对管理员有意义的权限,应用程序开发人员需要将低级操作分组到 Authorization Manager 任务对象中。

图 4:操作和任务

图 4:操作和任务
查看全尺寸图片。

定义任务

正如上面所提到的,应用程序需要为每个作为一个单元运行且必须受保护的例程定义操作。通过这使得应用程序可以更精确地授予访问权限,然而需要有多个操作执行应用程序对用户公开的高级任务。在这种情况下,您必须确定执行这一高级任务需要哪些操作,并为这个高级任务创建一个Authorization Manager 任务对象。这需要在管理方面做些研究。任务对象通过提供有意义的高级权限集来简化角色管理,这种高级权限集与管理员将授权用户执行的应用程序任务是对应的。因此,对于应用程序来说,安装完整的任务集来控制应用程序的所有使用权限是非常重要的。图 4 展示了如何使用任务对象来将权限组合成高级任务。

BizRules

Authorization Manager 任务对象具有根据附加的与任务相关的 VBScript 或 JScript 来动态限定在任务中授予的权限的附加功能。这可以使访问控制决策考虑运行时数据,例如:请求的开支的美元数额或请求的物品的库存。BizRules 在 AccessCheck 调用期间运行,并在调用 AccessCheck 的线程内的 Web 应用程序的上下文中运行。如果 BizRule 返回成功信息,则用户将接收到与该任务相关联的请求操作。如果 BizRule 失败,就不允许客户端执行与该任务相关联的操作。该用户通过一个独立的任务可能也可以执行这些操作。参数通过 AccessCheck 调用传递给 BizRule ,该调用将名称和值数组作为参数。例如,varParameterNames 数组中的第一个元素是对应于 varParameterValues 数组中的第一个元素的名称。BizRule 参数的名称数组(varParameterValues)必须相应地进行排序,以便名称和值具有同样的索引。

一个应用程序授权策略可以有多个任务。每个任务可以有相关联的 BizRule,也可以没有。应用程序管理员也可以添加新的任务和 BizRule。在设计阶段,应用程序开发人员并不知道调用 AccessCheck 时,是否需要指定 BizRule 参数(因为对 AccessCheck 的调用并不一定要用到 BizRule),因此应用程序必须发送 BizRule 可能需要的这些参数。为了方便 BizRule 开发人员,应用程序必须定义并发布被发送到每个 AccessCheck 调用的 BizRule 参数集。

AccessCheck 应该作为 BizRule 参数发送的数据类型包括诸如用户名和限制数据等信息。限制数据可能包括以下各项:限额、帐户或 ID 号,或者一个用户管理器。在运行时可能用于确定是否授予访问权限的任何数据都可以在每个 AccessCheck 调用中使用,并且必须包含在已发布的 BizRules 参数的应用程序列表中。

BizRules 要求用户具备一些脚本知识,因此并不适合让大多数管理员进行创建和修改。通常,BizRules 应该是与应用程序一起开发并提供的,或者由应用程序供应商提供,或者在以后由其他的开发人员进行开发。由于每个运行中的 BizRule 都调用 Windows Script Engine(Windows 脚本引擎),所以 BizRule 在计算上应该属于小任务,例如比较给定的参数或查询数据库。

样本 BizRule

下面是一个写入 JScript 的 BizRule,此处用一个 24 小时的时钟来保证它每天的工作时段在 9:00 至 17:00 之间:

AzBizRuleContext.BusinessRuleResult = false; dt = new Date(); hour = dt.getHours(); if (hour > 9 && hour < 17) {    AzBizRuleContext.BusinessRuleResult = true; } 

为了提供被频繁调用的 BizRule 的性能,针对客户端上下文的生命对 BizRule 的调用结果进行了缓冲。正因为这样,BizRule 才对时间敏感,正如上面的示例提到的。应用程序缓冲客户端上下文以便适当地缩短时间量。

下面是一个 Microsoft Visual Basic Scripting Edition (VBScript) BizRule,可保证作为名为 ExpAmount 的参数传递到 BizRule 的数值小于 500:

Dim Amount AzBizRuleContext.BusinessRuleResult = FALSE Amount = AzBizRuleContext.GetParameter("ExpAmount") if Amount < 500 then AzBizRuleContext.BusinessRuleResult = TRUE 

当 BizRule 引用一个参数时,AccessCheck 将针对客户端上下文生命的一个特定 BizRule,缓冲参数、值和结果。这样,以后对同一个客户端上下文进行 AccessCheck 调用时,如果还以同样的值引用同一个 BizRule,则可提高性能。这就意味着,如果在以后的 AccessCheck 调用中可以只改变 BizRule 的结果,而不改变 BizRule 参数(正如上面描述的 BizRule 当日时间)的话,那么所缓冲的值可能是不正确的。基于这个原因,使用 BizRule 的应用程序必须定期释放客户端上下文。

初始角色

有些应用程序具有少量的硬编码角色,例如:管理员(Administrator)、读者(Reader)和作者(Writer)。这些应用程序需要在启动时调用 Authorization Manager API 来创建这些初始角色。

确定作用域

Authorization Manager 作用域对象是资源的集合,既可以是简单的集合(如:C:/My Documents),也可以是更加抽象的集合(如:*.doc)。应用程序必须考虑它将使用何种逻辑来确定作用域。作用域给应用程序在将不同的访问控制应用到不同的资源上具有很大的灵活性。根据正在控制访问的是什么应用程序,可以相应地改变集合的形式。例如,如果应用程序执行其他计算机上的操作,那么作用域就可以表示为计算机对象的集合,并将其命名为“销售部门中的计算机”或者“运行 Windows XP 的计算机”之类的名称。惟一的要求是应用程序在执行访问验证时,必须能够将访问某一资源的用户请求映射到包含该资源的作用域中。

除了作为逻辑资源集合以外,作用域还给应用程序很大的灵活性来定位复杂的授权问题,例如将“work on behalf”特性纳入应用程序中。“work on behalf”特性可以让一个用户授权其他用户以他的名义执行工作。例如,假定 Bob 想让 James 以他的名义执行工作。在应用程序中,可以通过这样来实现:为 Bob 创建一个作用域,在该作用域中定义一个角色,用以指定 Bob 的权限的子集,并允许 James 使用这一子集。(James 即被分配到这个角色中了。)当 James 以 Bob 的名义连接并请求执行一个操作的权限时,就会执行 AccessCheck 操作,这一操作利用 Bob Work on Behalf 作用域来检验 James 是否具有以 Bob 的名义执行这些操作的权限。

由于作用域是由每个应用程序定义的,并且该应用程序将每个访问请求映射到适当的作用域中,因此应用程序应该提供有关文档,以便使管理员了解如何创建命名正确的作用域。

安装

在安装应用程序时,会通过调用 Authorization Manager API 来将授权策略信息安装到新的或现有的授权存储库中。如果该应用程序将授权策略安装在现有的存储库中,那么安装过程应该提供给执行安装的用户一种途径来指定现有存储库的位置。初始化授权策略存储库之后,安装程序会使用 CreateApplication 方法在策略存储库中创建一个应用程序对象。然后,对于每个操作,安装程序会调用 CreateOperation 方法。初始的任务、作用域和角色分别运用 CreateTaskCreateScopeCreateRole 方法加以安装。下面的 VBScript 为一个简单的开支应用程序创建一个存储库并安装授权策略。

'--- Initialize the admin manager object Dim pAzManStore Set pAzManStore = CreateObject("AzRoles.AzAuthorizationStore") '--- Create a new store for expense app ' 0 = Open store for Access Checking. ' AZ_AZSTORE_FLAG_CREATE   = 0x1, ' AZ_AZSTORE_FLAG_MANAGE_STORE_ONLY = 0x2, // cannot do access checking. ' AZ_AZSTORE_FLAG_BATCH_UPDATE      = 0x4, pAzManStore.Initialize 1+2+4, "msxml://C:/AzPolicy.xml" pAzManStore.Submit Dim App1 Set App1 = pAzManStore.CreateApplication("Expense") App1.Submit '--- Create operations ----------------------- Dim Op1 Set Op1=App1.CreateOperation("RetrieveForm") Op1.OperationID = CLng(61) Op1.Submit Set Op1=App1.CreateOperation("EnqueRequest") Op1.OperationID = CLng(62) Op1.Submit Set Op1=App1.CreateOperation("DequeRequest") Op1.OperationID = CLng(63) Op1.Submit Set Op1=App1.CreateOperation("UseFormCotnrol") Op1.OperationID = CLng(64) Op1.Submit Set Op1=App1.CreateOperation("MarkFormApproved") Op1.OperationID = CLng(65) Op1.Submit Set Op1=App1.CreateOperation("SendApprovalNotify") Op1.OperationID = CLng(66) Op1.Submit '--- Create tasks ------------------------------ Dim Task1 Set Task1=App1.CreateTask("Submit Expense") Task1.AddOperation CStr("RetrieveForm") Task1.AddOperation CStr("EnqueRequest") Task1.AddOperation CStr("UseFormCotnrol") Task1.Submit Set Task2 = App1.CreateTask("Approve Expense") Task2.AddOperation CStr("MarkFormApproved") Task2.AddOperation CStr("SendApprovalNotify") Task2.AddOperation CStr("DequeRequest") Task2.BizRuleLanguage = CStr("VBScript") Task2.BizRule = "Dim Amount" & vbnewline  & _            "AzBizRuleContext.BusinessRuleResult= FALSE" & vbnewline &_            "Amount = AzBizRuleContext.GetParameter( " & Chr(34) &_                               "Amount" & Chr(34) & ")"  & vbNewLine &_            "if Amount < 500 then AzBizRuleContext.BusinessRuleResult= TRUE" Task2.Submit '--- Create role definitions ------------------------------ Set Task3 = App1.CreateTask("Expense Admin") Task3.AddTask CStr("Approve Expense") Task3.AddTask CStr("Submit Expense") Task3.IsRoleDefinition = TRUE Task3.Submit Set Task4 = App1.CreateTask("Expense User") Task4.AddTask CStr("Submit Expense") Task4.IsRoleDefinition = TRUE Task4.Submit '--- Create initial scopes and roles ------------------------------ '--- only one scope in this app (we may instead choose to use no scope) Dim Scope1 Set Scope1 = App1.CreateScope("AllRoutines") Scope1.Submit Set RoleA=Scope1.CreateRole("Expense Administrator") RoleA.AddTask("Expense Admin") RoleA.Submit Set RoleB=Scope1.CreateRole("Expense User") RoleB.AddTask("Expense User") RoleB.Submit '--- Demo - add everyone to ExpenseUser Role -------------------------- RoleB.AddMemberName("Everyone") RoleB.Submit 

应用程序模型

使用 Authorization Manager 的应用程序使用下列受信任的子系统应用程序模型。请注意,这两个模型意味着完全不同的应用程序设计,基于折衷原则,一个特定的应用程序可能会选择使用一个混合的模型,它包含一个受信任的子系统中间层设计并使用角色模拟(impersonation)来维护后端审核,或者连接旧的后端资源管理器。

角色模拟模型

Windows 2000 和早期版本的 Windows NT Server 都支持 Windows NT 角色模拟模型。在这一模型中,服务器应用程序从已连接的客户端获得一个令牌,并在尝试进行安全操作(例如:打开一个文件)之前模拟该客户端令牌。将打开的这个文件中的 ACL 会与用户令牌组进行比较以便确定用户是否具有打开该文件的权限。而 Windows Server 2003 家族通过协议转换的 Kerberos 扩展和强制授权来增强对角色模拟模型的支持。

受信任的子系统应用程序模型

Authorization Manager 在 Windows 安全性基础结构中增加了对一种新的受信任的子系统应用程序模型的支持。

图 5:角色模拟模型和受信任的子系统模型

图 5:角色模拟模型和受信任的子系统模型
查看全尺寸图片。

在受信任的子系统模型中,应用程序服务器帐户具有足够的访问权限,所以它使用执行公开给客户端的所有操作。如果一个客户端请求一个操作,中间层应用程序服务器就会根据特定于该应用程序的授权策略来授权该客户端请求。如果该客户端具有执行所请求的操作的权限,那么服务器就会以该客户端的名义执行该操作。在这种模型中,客户端不需要直接访问资源。角色模拟模型是很强大的,可以应用于许多情况中,而受信任的子系统模型则具有该角色模拟模型所不具备的一些优点。

权限管理

在角色模拟模型中,每个客户端用户帐户都用于访问后端资源,因此必须通过授予每个用户适当级别的访问权限来维护所有资源的 DACL。当单独保护的资源的数量增加时,特别是当它们存储在独立的后端计算机中时,对 DACL 的管理就变得很繁重。举例来说,您可能会将资源组织到以同种的方式保护的单元中,例如以同样的方式在一个子树中保护所有的文件,或者将用户组织到具有相似权限的组中。

在受信任的子系统模型中,只有中间层服务帐户用于访问后端资源;因此,通过只授予该服务帐户足够的访问权限来执行所有该对象上的操作就可以简化 DACL。服务帐户不应该具有完全控制权限或者是本地管理员,但它必须具有足够的权限来执行应用程序的整套操作。应用程序设计人员可以在后端资源中对应用程序需要的权限级别进行文档化。这减少了对 DACL 的管理,因为只有服务帐户需要访问它们。该服务获得了访问资源的权限,因此您必须信任该服务将不会意外地让一个用户访问另一个用户的资源。

权限提取

在角色模拟模型中,通过将 DACL 分发到资源中来授权用户执行高级任务是很困难的。高级任务(如:提交开支或查询清单)可能需要对后端资源执行几项操作。权限提取 是准确确定高级应用程序操作需要哪些低级资源权限的过程。这可能是很费时的,特别是在使用了许多受保护的资源类型的情况下。

在实践中,有时为了节省时间,管理员会授予过多的访问权限。受信任的子系统应用程序模型可以让管理员只授予服务帐户访问权限。由于只局限让服务帐户访问资源,确定正确的访问权限就相对容易了:通常服务器会给予刚好够用的访问权限来执行服务器应用程序可能需要的所有操作(由应用程序设计人员定义)。管理员不需要在 DACL 中定义和维护不同级别的权限。

连接池

通常,利用连接池可以达到更佳的可伸缩性。由于角色模拟模型通过对资源服务器的请求来维护用户上下文,所以每个用户请求通常都需要独立连接到资源服务器上。如果您为每个客户端都创建了一个连接,那么您就可以避免重复使用一个连接来连接到资源服务器,如:一个 SQL 数据库。一个受信任的子系统服务器应用程序授权客户端的请求,并且为该应用程序服务帐户的上下文中的客户端访问远程资源。由于不需要建立新的连接,所以该应用程序服务器就可以使用同一条到资源服务器的连接为来自不同客户端的请求提供服务。

受控访问点

一些应用程序强制应用程序服务器中的规则和工作流。在角色模拟模型中,每个客户端都获得了对每个资源的适当访问权限。由于客户端具有直接访问资源的权限,所以它们可以通过一种方法来暗中访问资源,而不是通过有特定目的的应用程序来访问,因为这种方式会引起对资源的意外访问和操作。

在受信任的子系统中,只有应用程序服务帐户才有访问资源的权限。这就意味着用户不能直接通过一种工具或 API 来获得对资源的访问权限。在这种模型下,应用程序服务器对用户如何查看和操纵资源具有更大的控制力。

审核

审核可以让管理员确定哪些用户试图获得对特定资源的访问权。如果审核是由管理这些资源的同一个应用程序生成的,则具有最大的权威性。角色模拟模型是通过在用户请求访问每个系统时维护用户上下文来确定哪些用户试图访问特定资源的。这就可以让远程系统可信地记录用户及所请求的访问。

当您使用一个受信任的子系统应用程序模型时,后端资源管理器会生成审核,它将服务器的服务帐户记录为请求访问的帐户,而不是以其名义执行操作的客户端用户。在执行访问验证时(换句话说,在调用 AccessCheck API 时),Authorization Manager 提供运行时审核,但这些审核是在应用程序服务器上生成的。因为这一点,要将后端资源上的访问审核映射到发出请求的用户,就要求应用程序服务器上的审核日志与后端审核相关联。在应用程序服务器中,您可以知道更多关于客户端正在请求的高级任务的信息,所以在审核中能够记录更大程度的用户意图。在后端资源管理器中,只可以审核低级的操作请求,因此要确定用户更高级的活动可能就比较困难了。

其他区别

在角色模拟模型中,运行应用程序服务器的服务帐户可能很少或者没有访问资源。为了以客户端的名义访问资源,应用程序服务器必须模拟客户端安全上下文,在客户端连接到应用程序服务器时,应用程序服务器能够获得该客户端的安全上下文。如果您限制了服务器上下文的权限,当一个对服务器有威胁的攻击得逞时,对服务器的访问权限就会限制为所连接的客户端的权限。如果攻击者想要获得对后端数据的高度访问权,他们就必须威胁该服务器并等待用户来连接。随着某一用户连接到一台受威胁的服务器上,攻击者的访问权限就会与所连接的用户的权限成比例增长。如果一个具有很高权限的帐户登录到这台服务器上,那么攻击者也获得了对这些资源的访问权限,因为他们具有模拟该客户端访问这些资源的能力。

一个受信任的子系统服务器一开始就具有对应用程序资源的高度访问权限,所以如果这台服务器受威胁,那么攻击者就获得了对这些资源的高度访问权限。但由于客户端不会被模拟,攻击者就只限于访问访问服务上下文(应用程序的资源)。攻击者获得了对应用程序资源的高度访问权,但不能够访问非应用程序资源。

返回页首返回页首

开发 Authorization Manager 应用程序

服务器应用程序运用 Authorization Manager 运行时接口来管理对授权策略存储库的连接以及检验客户端请求。

初始化

当应用程序运行时,它使用 IAzAuthorizationStore::Initialize 接口来初始化 Authorization Manager 策略存储库。应用程序必须对授权存储库具有读取权限,但不需要有写入权限。连接到存储库之后,应用程序就调用 IAzApplication::Initialize,用以对策略存储库中的特定应用程序初始化一个接口。

客户端连接

当一个客户端连接到应用程序中时,必须为该用户创建一个 Authorization Manager 上下文。可以应用 IAzApplication::IntiializeClientContextFromTokenIAzApplication::AzInitializeClientContextFromStringSID 或者 IAzApplication::InitializeClientContextFromName 方法来创建。通常如果有一个令牌可用,则可以使用令牌来创建上下文。令牌通常是一个 Windows 登录结果,包含有登录信息(例如:其是否属于交互式登录或网络登录)。通过令牌创建上下文通常会比较快,因为它不需要为获得组信息而查询域控制器。在少数情况下,有可能需要根据这些登录特性提供角色分配,所以如果可以,请使用 FromToken 形式的 InitializeClientContext API。例如,如果一个用户以交互方式登录到网络,则在产生的令牌中会添加 NT AUTHORITY/INTERACTIVE 组。运用 InitializeClientContextFromName(或 SID)方法,可以通过查找在 Active Directory 中分配的用户组来创建 IAzClientContext 对象。由于该用户还没登录进来,上下文不会包含某些组,包括标识登录类型的 NT AUTHORITY/INTERACTIVE 组。在这种情况下,如果一个组或角色中的成员是在交互组中给定的,那么运用 InitializeClientContextFromName 创建的用户上下文将接收不到该成员。建议您不要将这些登录特性组运用到安全的资源中,或者在组或角色中指定成员,这样就可使用 InitializeClientContextFromName InitializeClientContextFromSID 方法了。

AzInitializeClientContextFromStringSID 方法以文本格式从一个给定的 SID 创建 Authorization Manager 上下文。它与 InitializeClientContextFromName 方法的方法相类似。如果使用了 AZ_CLIENT_CONTEXT_SKIP_GROUP 标记,那么 AzInitializeClientContextFromStringSID 方法就不能够尝试确定给定 SID 的组成员。这样所产后的客户端上下文就只包含特定的 SID。如果 IAzAccessCheck 方法从这个客户端上下文实例进行调用,那么只在将这个特定的 SID 当作一个角色的成员或者分配给一个角色的组的成员使用时才授权角色成员。

角色查询和授权

在创建了一个客户端上下文之后,应用程序就可以查询与该用户有关的角色信息,以便根据该用户角色成员来呈现用户界面。例如,一个基于 Web 的应用程序可以将经理用户界面呈现给担当经理角色的用户,并将其他的所有人都归为雇员角色。IAzClientContext::GetRoles 方法列举了用户角色成员。由 GetRoles 返回的角色集只是基于显式的成员分配;GetRoles 并不评估 BizRules。

当该用户产生一个请求时,应用程序就会将该请求映射到所需的操作上并确定用户是在哪个作用域上产生请求的。然后应用程序调用 AccessCheck 来发送这个作用域、所请求的操作、BizRule 参数和对象名称。这个作用域可确定用户角色成员,并由该用户角色成员来确定是否授予该用户访问权限。

返回页首返回页首

性能

应用程序初始化和访问权限检验的性能会因应用程序使用诸如 XML 存储、BizRules 和 LDAP 查询组等特性的方式而异。应用程序设计人员有几个方面需要考虑以便满足性能需求。

应用程序初始化性能

在您使用 Active Directory 存储库而不是使用 XML Authorization Manager 存储提供者时,大型存储库的加载时间会得到改善。当一个应用程序初始化一个到 Authorization Manager 策略存储库的连接时,授权策略会被加载到应用程序的地址空间中。加载的策略的数量取决于存储类型。

Active Directory Authorization Manager 策略存储库允许根据需要加载或卸载 Authorization Manager 应用程序对象,并允许只在需要时才加载 Authorization Manager 作用域对象。(要获得更多的信息,请参阅本文前面的“Active Directory Authorization Manager 存储”。)

XML Authorization Manager 存储提供者将整个授权策略都加载到内存中。

另外,初始化所花的时间随着 Authorization Manager 策略存储中的对象的数量增加而增长,或者随着 Authorization Manager 应用程序基本组中的成员的数量增加而增长。为了最小化应用程序组的容量,请在条件允许的情况下使用 Active Directory 组策略,然后在 Authorization Manager 应用程序组或角色中运用这些 Active Directory 组。

AccessCheck 性能

运用 Authorization Manager AccessCheck 方法提供了一种灵活的方式来优化使用 BizRules 和 LDAP 查询组的性能。

AccessCheck 方法:

1.

识别应用于 AccessCheck 例程的作用域,可以是指定作用域中的例程,也可以是全局作用域中的例程。

2.

步骤 1 中列举了作用域中的角色集。

3.

丢弃(Discards)角色并不涉及所请求的操作。如果指定了 RoleForAccessCheck,则这些指定的角色以外的角色都将被丢弃。

4.

检验每个角色中的客户端安全上下文成员资格。

5.

如果这个客户端是步骤 4 中的角色的成员,则 AccessCheck 记录所有在授权时分配给该角色的请求操作。

6.

如要应用作用域的每个角色,请重复执行步骤 3 至 5。

以上的逻辑最多重复三遍。

1.

在第一遍中,AccessCheck 忽略所有包括 BizRules 的任务,以及所有包含 LDAP 查询的应用程序组。BizRules 和 LDAP 查询计算需要占用很长时间,并且需要网络操作,所以第一遍是在不需要上述任务和组的情况下进行的。

2.

在第二遍中,AccessCheck 处理 BizRules,但仍然忽略 LDAP 查询组。假定 BizRules 很简单,不包括网络操作,所以它们在处理时可能比 LDAP 查询来得快。

3.

第三遍处理所有的数据,包括 LDAP 查询,其使用以前迭代过程中缓冲的结果。在授权访问所有请求的操作时 AccessCheck 随即终止。

由于对 AccessCheck 进行优化用以先评估静态成员资格,后评估动态成员资格,并且先评估不带 BizRules 的任务,后评估带 BizRules 的任务,在可能的情况下,您可以运用静态分配的方式来优化性能。

直到调用 AccessCheck,并查询一个角色中的成员资格时才会对 Authorization Manager 应用程序组进行评估。(这种组评估的过程也称作 late-bound。)对于 LDAP 查询应用程序组,一旦为一个用户在应用程序组中建立成员资格,该 LDAP 查询组中的用户成员资格就会针对该用户上下文对象的生命进行缓冲。由于这一点,以后包含组评估的 AccessCheck 调用都会加速,因为已经解析了组成员资格,并对其执行了缓冲。

作为最佳实践,BizRules 必须经过计算,保持较小的值。在 AccessCheck 调用中,BizRules 提供了最大限度的灵活性,因此也就最大限度地降低了性能。网络会使 BizRules 降低 AccessCheck 的性能。通常这是不可避免的,例如,如果需要查询数据库来检验审核历史,但这种查询将延迟返回给用户的结果。

返回页首返回页首

特定于环境的设计事项

Authorization Manager 针对运用受信任的子系统应用程序模型而设计,其中访问权限检验是在服务器的上下文中完成的,同时后端服务器资源中的 ACL 只需要授予应用程序服务器服务帐户访问权限。(要想了解更多信息,请参阅本文前面的“受信任的子系统应用程序模型”。)为了使用受信任的子系统模型,通常应用程序服务器会在专门的服务帐户的上下文中运行。由于应用程序需要从 Authorization Manager 策略存储库中读取 Authorization 策略信息,所以运行应用程序的安全上下文需要具有该存储库的读取权限。您可以这样来实现:指明这个专门的服务帐户为 Authorization Manager 策略存储库的读者(Reader)。这些操作可以通过 Authorization Manager MMC(Microsoft Management Console,Microsoft 管理控制台)来完成。

如果在应用程序中使用了角色模拟,那么您在调用 Authorization Manager API 时就不能够模拟客户端了。惟一例外的情况是当您想要从所模拟的线程上下文初始化一个客户端上下文时。在这种情况下会调用 IAzApplication::InitializeClientContextFromToken 方法并指定 0 作为 ullTokenHandle 参数。其他的 Authorization Manager 接口读取 Authorization Manager 授权策略存储库(包含用户角色信息),同时 IAzApplicatin::AccessCheck 函数运行 BizRules 并解析 LDAP 查询组。由于用户需要有高度的访问权才能读取授权策略并执行 BizRule 脚本操作,所以在模拟该用户的安全上下文时您就不能够调用这些函数。每个 Windows 编程环境都为您提供了不同的选项,供您用于管理角色模拟并调用来自该应用程序的服务帐户的 Authorization Manager。

ASP.NET

在 ASP.NET 中编写的应用程序服务器可以通过 .NET 框架中的 /AuthMan 目录里附带的 .NET Interop 来使用 Authorization Manager API。为了在 ASP.NET 中创建一个受信任的子系统模型,您需要在一个服务帐户下运行应用程序服务器。为了配置您的 ASP.NET 应用程序,使之能在一个服务帐户下运行,您需要创建一个独立的 IIS 6.0 工作者进程(worker process),其运行于为该应用程序服务器创建的服务帐户的安全上下文中。然后再配置您的 ASP.NET 应用程序,使之能够使用这个专门的 IIS 工作者进程。为了了解关于 IIS 6.0 工作者进程的更多信息,请参阅 Microsoft Web 站点中的“Microsoft Internet 信息服务”页面:http://www.microsoft.com/technet/prodtechnol/windows2000serv/technologies/iis/default.mspx。另一种选择是运用 ASP.NET 来配置运行应用程序的上下文,将 Web.config 文件应用到您的 ASP.NET 应用程序中。在这种情况下,您必须配置该 ASP.NET 应用程序,使之能作为一个专门的服务帐户运行。

您的 ASP.NET 应用程序在初始化时会调用 AzAuthorizationStore.Initialize 来连接到 Authorization Manager 存储库上,然后调用 AzApplication.Initialize 来加载应用程序授权策略的初始百分比。

在运行时,如果有一个客户端建立了连接,您就可以从该客户端的帐户名称或者从代表该客户端的令牌创建一个用户上下文。这个令牌可以通过 ASP.NET HttpWorkerRequest 对象,在 ASP.NET 中检索到。Authorization Manager 也可以从一个客户端 SID 初始化一个上下文,虽然这种方式并不总在 ASP 或 ASP.NET 中可用。建议您如果可能的话,就应该从一个令牌初始化 Authorization Manager 上下文,因为从一个令牌初始化时,就不需要查询该用户帐户对象。这可能需要通过网络查询 Active Directory。

以下代码通过 ASP.NET 调用 Authorization Manager API,利用一个 .NET Interop 集合来批准一个开支核定。这些代码是一个简单的 Web 开支应用程序,在一个专门的服务帐户下运行。用于这个应用程序的 Authorization Manager 策略存储库可以通过本文前面所提到的 VBScript 安装脚本来创建。

<%@ Page Language="C#" Debug="True"%> <%@ Assembly Name ="Microsoft.Interop.Security.AzRoles"%> <%@ Import Namespace="Microsoft.Interop.Security.AzRoles"%> <%@ Import Namespace="System.Runtime.InteropServices" %> <html>    <head>    </head>    <body>       <%       Microsoft.Interop.Security.AzRoles.AzAuthorizationStoreClass AzManStore =             new Microsoft.Interop.Security.AzRoles.AzAuthorizationStoreClass();       // Keep the authorization store in a safe place out of the Web space.       AzManStore.Initialize(0, @"msxml://D:/SecureDir/MyWebAppsAzStore.xml",                             null);       IAzApplication azApp = AzManStore.OpenApplication("expense",null);       HandleRef token = new HandleRef(this, ((HttpWorkerRequest) ((IServiceProvider)Context).GetService(typeof(HttpWorkerRequest))).GetU serToken()); //-------------- Create Client Context --------------       IAzClientContext context = azApp.InitializeClientContextFromToken(                         (UInt64)token.Handle,                         0);       object[] scope = new Object[1];       scope[0] = "";       object[] operations = new Object[1];       operations[0] = 55; //--------------- Do access check -------------------- //Set up BizRule params. To optimize performance, name/value pairs must //be placed in array alphabetically       Object[] BRNames = new Object[1];       BRNames[0] = "ExpAmount";       Object[] BRValues = new Object[1];       BRValues[0] = Convert.ToInt32(Request.QueryString["Amount"]);       object[] results = (object[]) context.AccessCheck("Approve",                                                         scope,                                                         operations,                                                         BRNames,                                                         BRValues, .null,null,null);       bool bAuthorized = true;       foreach (int iResCode in results)       {          if ( iResCode != 0 ) // zero = no error          {            bAuthorized = false;            break;          }       }       Response.Write((string)context.UserSamCompat + "<br>");       Response.Write(              "Approval of " + Convert.ToString(BRValues[0]) + " was");       if (bAuthorized) {          %><font color="#008000"><b>APPROVED</b></font><%       } else {          %><font color="#FF0000"><b>DENIED</b></font>.<%       }       %>    </body> </html> 

ASP

运用 Authorization Manager 的应用程序通常会使用受信任的子系统模型。通过设计,IIS 应用服务提供者(Application Service Providers,ASP)应用程序模拟每个已连接的客户端的上下文。为了在 ASP 中使用受信任的子系统模型,您有两种选择:

选择 1:使用 Internet Information Services 6.0 URL 授权并模拟 Web 支出服务帐户。

创建一个独立的 IIS 6.0 工作者进程,运行于为 ASP 应用程序创建的安全性上下文。这将在用于这个 ASP 应用程序的一个专门的服务帐户下运行 IIS 和 ASP 的一个实例。在正常情况下,ASP 应用程序是以模拟已授权用户来运行的。IIS 6.0 URL 授权可以让您配置该 ASP 应用程序,使之在该 IIS 工作者进程的上下文中运行。由于您已经建立了 IIS 工作者进程并在应用程序服务帐户下运行,我们就可以使用 IIS 6.0 URL 授权,在那个安全性上下文中运行 ASP 应用程序。IIS 集成授权仍然会验证客户端,但它不会模拟该客户端,而是由 IIS 6.0 URL 授权使 ASP 应用程序在该服务帐户下运行。如果一个客户端建立了连接并由 IIS 进行身份验证,那么您可以使用 ASP 服务器变量 AUTH_USER 来检索该客户端的授权名称并调用 AzApplication.InitializeClientContextFromName 来为该客户端创建一个 Authorization Manager 上下文。如要了解关于 IIS 6.0 URL 授权的更多令牌,请参考本文后面的“IIS 6.0 URL 授权”。

以下代码是一个 ASP 应用程序,使用 Authorization Manager 来验证支出批准。该代码假定 ASP 应用程序模拟一个专门的服务帐户,而不是模拟该客户端安全上下文。如上所述,该应用程序被设定运用 IIS 6.0 URL 授权来模拟 IIS 工作者进程。

<%@ LANGUAGE="VBSCRIPT" %> <HTML> <HEAD> </HEAD> <BODY> <% Dim CCHandle Dim Results Dim Names(5) Dim Values(5) Dim Scopes(5) Dim Operations(10) Dim AzManStore Dim App Dim UserName Set AzManStore = CreateObject("Azroles.AzAuthorizationStore") 'Set myUser = Session.GetObject("LDAP") UserName = Request.ServerVariables("LOGON_USER") AzManStore.Initialize 0, "msxml://D:/Inetpub/wwwroot/MyWebAppsAzStore.xml" set App = AzManStore.OpenApplication ("Expense") '--------------- Create Client Context -------------- Set CCHandle = App.InitializeClientContextFromName(UserName) '--------------- Do access check -------------------- 'Set up BizRule params. To optimize performance, name/value pairs must be 'placed in array alphabetically Names(0) = "ExpAmount" Values(0) = 0 Names(1) = "Param2 for BizRule - Name" Values(1) = "Param2 for BizRule - value" Scopes(0) = Empty Operations(0) = 55 If Len(Request.QueryString("amount")) > 9 Then     Response.Write "Amount field is too long, please try again." Else    Set reg = New RegExp    reg.Pattern = "/D+" ' Look for something other than 0-9's.    if reg.Test(Request.QueryString("amount")) = False then       Values(0) = Clng(Request.QueryString("amount"))       '-------- AccessCheck -----------------------------------------       Results = CCHandle.AccessCheck("Approve",                                      Scopes, Operations, Names, Values)       If Results(0) = 0 Then ' Zero = NO_ERROR          Response.Write "Approval of " & Values(0) & " was accepted."       Else          Response.Write "Approval of " & Values(0) & " was denied."       End If       '--------------------------------------------------------------    Else       Response.Write "Must enter number, please try again"    End if End If Set CCHandle = Nothing set App = Nothing Set AzManStore = Nothing %> </BODY> </HTML> 

选择 2:创建自定义 COM 对象和接口来控制角色模拟。

创建一个允许您通过 ASP 应用程序来控制角色模拟的自定义 COM 对象。在这之后,建立 IIS 工作进程使之运行于一个服务帐户(如上所述),并运用这个自定义 COM 对象来调用 RevertToSelf API,并返回给 IIS 工作者进程上下文(ASP 应用程序服务帐户)。接下来调用 ImpersonateSelf API 来模拟该 IIS 工作者进程的上下文。(ASP 需要在角色模拟下运行应用程序。)在本步骤中保存客户端令牌很重要,因为以后会用到。

通过从自定义 COM 对象模拟 IIS 工作者进程,您可以调用 Authorization Manager API 来初始化 Authorization Manager 策略存储库和 ASP 应用程序服务帐户的上下文(您配置的工作者进程所要使用的安全上下文)中的 Authorization Manager 应用程序。初始化 Authorization Manager 策略存储库和应用程序对象的过程只在 ASP 应用程序初始化时才执行。

当产生了一个客户端请求时,您必须创建一个 Authorization Manager 客户端上下文,用它来检验该客户端的访问权限。为了创建这样的客户端上下文,您可以使用 ASP 服务器变量 AUTH_USER 来获取客户端的用户名称并调用 AzApplication.InitializeClientContextFromName. 。但您可以选择通过自定义 COM 对象,使用登录令牌来创建客户端上下文。可以这样来做:在您的自定义 COM 对象中公开一个函数,用它来检索您在前面所存储的令牌,并调用 ImpersonateLoggedOnUser API,从而模拟该客户端的安全上下文。然后,使用参数为 (0,0) 的 AzApplication.InitializeClientContextFromToken 方法来创建 Authorization Manager 客户端上下文,这样就能够从当前的线程令牌创建 Authorization Manager 上下文了。由于您正在模拟该客户端,所以当前的线程令牌就代表该客户端,同时由该令牌创建的 Authorization Manager 客户端上下文也可代表该客户端。完成之后,请使用您的自定义 COM 对象来再次模拟该 ASP 应用程序服务帐户,如上所述。

这种方式是可行的,因为我们是在为令牌句柄指定数值 0 的情况下调用 AzApplication.InitializeClientContextFromToken,API 所创建的 Authorization Manager 上下文是源自所调用线程的令牌。在这种情况下,由于我们模拟了客户端用户,所以所创建的 Authorization Manager 上下文就会代表该客户端。

实现一个自定义 COM 接口来管理角色模拟需要执行其他工作,但是使用一个自定义的 COM 对象来控制角色模拟却有如下好处,即可以使用在 IIS 中保留的客户端令牌来创建所描述的上下文。使用 AzApplication.InitializeClientContextFromName 接口的方法可查询 Active Directory 中的用户帐户对象。它在性能方面会比使用令牌时差一些,因为令牌已经含有这一信息了。

C、C++ 和 Visual Basic

您可以采用本地 C、 C++ 或 Visual Basic 语言,通过调用各种上下文管理 API(如:ImpersonateLoggedOnUser、OpenThreadToken 或 RevertToSelf)来控制角色模拟。在这些语言中,应用程序服务器可以安装为 Windows System 服务,并在该服务应用程序的一个专门的帐户下运行。在应用程序初始化时,它首先调用 AuthorizationStore.Initialize 来连接 Authorization Manager 策略存储库并从中加载信息,然后调用 AzApplication.Initialize 对策略存储库的应用程序策略创建一个 COM 接口。

当一个用户登录到应用程序中时,它使用所选择的任何手段来验证该客户端。如果使用了一个本地 Windows 验证机制,如:安全支持提供者界面(Security Service Provider Interface,SSPI)、分布式组件对象模型(Distributed Component Object Model,DCOM)、远程过程调用(Remote Procedure Call,RPC)或命名管道(Named Pipes),那么应用程序服务器就会运用其产生的令牌,用以下两种方法之一创建一个 Authorization Manager 上下文:

使用适当的角色模拟 API 来模拟客户端,例如:SSPI 中的 ImpersonateNamedPipeClient 或 ImpersonateSecurityContext,并调用 IAzApplication::InitializeClientContextFromToken,指定 0 作为令牌的句柄值。

查询客户端的令牌句柄,例如:SSPI 中的 QueryContextAttributes,并在调用 IAzApplication::InitializeClientContextFromToken 的过程中使用该句柄。

如果使用了非本地的 Windows 验证机制,那么应用程序可以将所验证的客户端映射为一个 Windows 帐户,然后使用 IAzApplication::InitializeClientContextFromName API,在验证完成后为客户端所映射的 Windows 帐户指定名称。

返回页首返回页首

Internet Information Services 6.0 URL 授权

Windows Server 2003 家族随附的 Internet Information Services(IIS) 6.0 集成了 Authorization Manager,从而实现 IIS 6.0 URL 授权,为应用程序管理员提供了控制访问 URL 的能力。这种能力是基于自定义用户角色、LDAP 查询和 BizRules 来实现的。

授权用户访问 IIS 中的 Web 页面要求管理 Web 应用程序所使用的资源中的众多 DACL。用于 Web 应用程序的资源可能包括 Web 页面文件、数据库记录、注册码等等。管理员如果要维护 DACL,需要准确知道每个对象要想在 Web 应用程序中执行有意义的任务需要什么样的后端权限。IIS 6.0 URL 授权可以让管理员通过授权用户访问组成 Web 应用程序的 URL 来简化访问管理。当一个用户请求一个 URL 时,IIS 6.0 URL 授权会基于用户角色检验该用户的访问权限。这可以让管理员控制所有对 URL 的访问,而不是控制每个对象上的每个 DACL,通过这样来简化访问控制管理。Web 应用程序可以运用 Authorization Manager 基于角色的框架来进一步限制对资源的访问。

IIS 6.0 URL 是作为一个 ISAPI interceptor.dll 予以实施的,被配置为一个应用程序、虚拟目录或 URL 的通配符扩展。当配置一个应用程序、虚拟目录或 URL 来使用 IIS 6.0 URL 授权时,每个对 URL 的请求都被路由到 URL 授权 ISAPI 拦截器(interceptor)上。IIS 6.0 URL 授权 ISAPI 拦截器会使用 Authorization Manager 运行时来授权访问所请求的 URL。为了实现这一些,URL(应用程序、虚拟目录或单个的 URL)必须与一个包含该 URL 的授权策略的 Authorization Manager 策略存储相关联。一旦客户端被授权访问该 URL,则 IIS 6.0 URL Authorization ISAPI 将请求传递给处理该 URL 的合适的处理程序,如:ASP、ASP.NET ISAPI 或者静态文件处理程序。

图 6: IIS URL 授权。

图 6: IIS URL 授权。
查看全尺寸图片。

使用 IIS 6.0 URL 授权,管理员可以根据只在运行时可用的信息来控制访问 URL。例如,您有一个 Web 页面,其只对一个给定的成本中心中的雇员可视,或者对特定年龄的雇员可视,那么您可以根据 LDAP 查询(其用于检查用户对象的成本中心属性或年龄属性),将角色分配给正确的用户。如果雇员只能在一周中的某几天,或者在一天中的某段时间内访问特定的页面,那么可以创建一个 BizRule,根据这些数值或可在运行时所声明的任何值(包括 IIS 服务器变量)来授权访问该 URL。

设置 IIS 6.0 URL 授权

如要使用 IIS 6.0 URL 授权,可以在应用程序、虚拟目录或 URL 中设置 Metabase 属性:

AzEnable:为对应于 Metabase 中的条目的虚拟目录、应用程序或 URL 启用 URL 授权。

AzStoreName:使 Authorization Manager 存储库与虚拟目录、应用程序或 URL 相关联。

AzScopeName:使虚拟目录、应用程序或 URL 与作用域相关联。在 AzStoreName 属性引用的 Authorization Manager 策略存储中,该作用域是 IIS 6.0 URL 授权应用程序内的作用域的名称。如果它指定一个空的字符串,或者根本没有指定作用域,那么就使用 IIS 6.0 URL 授权的默认作用域。

AzImpersonationLevel:可确定应用程序的角色模拟行为。这使得您可以配置 Web 应用程序来模拟客户端用户、IIS 工作者进程或工作者进程的 IUSER_* account。每种设置都大大改变了 Web 应用程序的环境和隐含的设计。将该值设置为 0、1 或 2,以与所预计的角色模拟方式相对应。

0:模拟授权客户端。有些应用程序需要客户端角色模拟,如:ASP 2.0 应用程序。对于期望在模拟客户端的同时运行的应用程序(比如 ASP 2.0 应用程序),如果您想要使用 URL 授权,您就可以使用该值。

1:模拟 IIS 工作者进程。当应用程序在受信任的服务上下文中作为服务帐户运行,授权每个客户端请求本身和执行请求的操作时,请使用该值。如要获得更多的信息,请参见本文前面的“受信任的子系统应用程序模型”一节。

2:模拟匿名的用户帐户。这使得您可以使用 URL 授权来授权客户端在访问该 URL 的同时仍然作为匿名帐户运行该 Web 应用程序,以限制所有通过 Web 应用程序进行的客户端访问。

以下脚本使用 ADSI 来为应用程序、虚拟目录或 URL 在 IIS Metabase 设置这些属性。

'  SetUrlAuth.vbs '  Configuring UrlAuth with a Vdir. '  This script uses ADSI to configure a vdir in the IIS 6.0 metabase. to use '  IIS 6.0 URL authorization. ' '  This script assumes that the IIS vdir corresponding to the application has '  already been created. ' '  After running this script to verify the settings, use the Adsutil tool like so ' '  inetpub/adminscripts/adsutil enum w3svc/1/root/MyApp '  (where MyApp is the app name) '  Use the Authorization Manager MMC snap-in to do the following: '     Create an application called "IIS 6.0 URL Authorization" '     Create an operation called "AccessURL" with an operation ID of 1 '     Create a scope corresponding to the AzScopeName specified to this script. '       This scope name will be used to manage access to URLs in this Vdir '     Make sure that the IIS worker process has read access to the '       AzMan policy store. You can do this using the AzMan UI (right click '       store and select options and then the security tab Set objArgs = WScript.Arguments If objArgs.count < 4 then   wscript.echo "Usage: SetUrlAuth VDirPath AzScopeName AzStoreName AzEnable [ImpersonationLevel]"   wscript.echo ""   wscript.echo "Example:"   wscript.echo " SetUrlAuth w3svc/1/root/MyApp MyApp msxml://d:/inetpub/wwwroot/AzStore.xml True 1"   wscript.echo ""   wscript.echo "Run with 'cscript' command in cmd.exe to avoid msg boxes" Else wscript.echo objargs(0) ' ' Get interface to the Vdir object ' DIM iis set iis = GetObject("IIS://localhost/" & objArgs(0)) ' Set scope name - this scope will preside over URLs referring to this vdir ' This scope must exist in the corresponding Authorization Manager store. ' iis.AzScopeName = objArgs(1) ' ' Specify location of Authorization Manager policy store ' iis.AzStoreName = objArgs(2) ' ' Enable urlauth for this Vdir ' iis.AzEnable = objArgs(3) ' ' Set Impersonation Level ' If objArgs.count > 4 then    iis.AzImpersonationLevel = objArgs(4) End if ' ' Write settings to Metabase ' iis.SetInfo End if 

当请求 Web 页面时,URL 授权将根据 Authorization Manager 授权策略来授权客户端(如果允许客户端访问该 URL 的话)。如果想要通过 AzImpersonationLevel 配置安全性上下文来检索 URL 数据(如:.htm 文件),就需要正确的 IIS 目录安全性和 NTFS 权限。通过 IIS URL 授权,您可以使用受信任的子系统模型,更轻松地维护 NTFS 权限。如要获得更多的信息,请参见本文前面的“受信任的子系统应用程序模型”一节。

在配置 IIS 6.0 URL 授权时,您可以通过 IIS Metabase 条目中的 AzStoreName 属性为应用程序、虚拟目录或 URL 标识 Authorization Manager 策略存储库。如要管理授权策略,可以遵循下列步骤:

1.

单击“开始”按钮,再单击“运行”,键入 Azman.msc,然后按回车键。

2.

在控制台树中,右键单击“授权管理器”,然后单击“打开授权存储库”。

3.

存储库名称中,键入授权存储库所位置的路径,其由 AzStoreName 属性进行标识,然后单击确定

如要获得更多关于打开授权存储库的信息,请参见 Authorization Manager MMC 帮助中的“授权存储库和应用程序”章节。

该存储库的 IIS 6.0 URL 授权通过 IIS 6.0 URL Authorization 应用程序进行管理。元库(Metabase)中的 AzScopeName 属性在 IIS 6.0 URL Authorization 应用程序中予以管理。可使用该作用域来管理对相应的 URL 的访问。在配置应用程序时,必须在授权策略存储中创建具有与对应的元库条目的 AzScopeName 属性中所指定的名称相同的作用域。

下图展示的 Authorization Manager MMC 带有的授权策略存储库可以用于管理对 Web Expense 应用程序和 Web Application 2 的访问。该存储还包含这些应用程序的授权策略。

图 7:管理两个 Web 应用程序的授权管理器

图 7:管理两个 Web 应用程序的授权管理器
查看全尺寸图片。

IIS 6.0 URL 授权的授权策略存储在 Active Directory 或 .xml 文件的 Authorization Manager 策略存储库中。通过 IIS 6.0 URL 授权,您可以在与使用 Authorization Manager 来控制对应用程序任务和操作的访问的 Web 应用程序相同的授权策略来维护 URL 的授权策略。通过在相同的存储中维护授权策略,管理员可以从相同的 Authorization Manager MMC 或自定义用户界面来管理对 URL 和 Web 应用程序资源的访问。这为管理 URL 和应用程序提供了通用的访问点,而通过这种方式还可以用相同的 Authorization Manager 组合 LDAP 查询,同时植入 URL 授权和应用程序授权的角色。

按步骤配置 IIS 6.0 URL 授权

以下步骤为一个称为 WebApp 的 Web 应用程序建立 IIS 6.0 URL 授权,其安装在 Systemroot/InetPub/WWWroot/WebApp 文件夹中,并在 IIS 中配置为应用程序:

注意: 使用 IIS URL 授权的 URL 要求具有 Windows 集成身份验证(Integrated Windows Authentication)。IIS Web 应用程序和虚拟目录默认启用 Windows 集成身份验证。有关配置 Windows 集成身份验证的信息请参考“Internet 信息服务在线帮助”中的“ Windows 集成身份验证”。

建立 IIS:在“默认 Web 站点”下创建您的应用程序文件夹,然后禁用匿名访问该站点。

1.

单击“开始”菜单,单击“运行”,键入 %systemroot%/System32/InetSrv/IIS.msc,然后按回车键。

您也可以单击“开始”菜单,单击“管理工具”,然后单击 Internet Information Services(IIS)管理器

2.

在控制台树中,双击“Internet 信息服务”,双击计算机名,再双击“Web 站点”,然后双击 默认 Web 站点,右键单击对应于您的 Web 应用程序的文件夹,单击“特性”,然后单击“创建”。

3.

单击“目录安全性”选项卡,然后在“授权和访问控制”中单击“编辑”。

4.

确认“启用匿名登录”复选框没有被选中,单击“确定”,然后再次单击“确定”。

设置通配符配置特性以使之指向 URLAuth.dll

1.

Internet 信息服务(IIS)管理器中右键单击您创建的 Web 应用程序所在的文件夹,单击“特性”,然后单击“配置”。

2.

在 “通配符应用程序映射(执行顺序)” 中单击“插入”。

3.

在“添加/编辑应用程序扩展映射”中单击“浏览”,在“文件类型”中选择所有文件(*.*)

4.

定位到 Systemroot/System32/InetSrv 文件夹。

5.

单击 URLAuth.dll,再单击“打开”,单击“确定”,单击“确定”,然后再单击“确定”。

如果您得到一个错误消息“执行路径已被使用”,则表明 URLAuth.dll 已被配置为一个通配符应用程序扩展映射了。

添加 URLAuth.dll 作为一个新的 Web 服务扩展

1.

在控制台树中,双击“Internet 信息服务”,双击计算机名,然后单击“Web 服务扩展”。

2.

在详细信息窗格中,单击“添加一个新的 Web 服务扩展”。

3.

单击“添加”,再单击“浏览”,定位到 Systemroot/System32/InetSrv/,单击 URLAuth.dll,再单击“打开”,然后单击“确定”。

4.

扩展名中键入 URL 授权

5.

选中“将扩展状态设置为允许”复选框,然后单击“确定”。

在 Authorization Manager 中建立授权策略存储

1.

单击“启动”按钮,再单击“运行”,键入“Azman.msc”,然后按回车键。

2.

在控制台树中,右键单击“Authorization Manager”,然后单击“选项”。

3.

确认选择“开发者模式”,然后单击“确定”。

现在我们来创建一个新的存储库。对于这个示例,我们将存储库放在 C:/ 盘,并将它命名为 “MyStore.xml”。

4.

在控制台树中,右键单击“Authorization Manager”,然后单击“新建授权存储库”。

5.

单击“XML 文件”,并在“存储名称”中键入 C:/MyStore.xml

6.

(可选)在“描述”中键入关于这个新存储库的信息。

7.

单击“确定”。

8.

在控制台树中,右键单击 MyStore.xml,并单击“新建应用程序”。

9.

在“新建应用程序”的“名称”中键入 IIS 6.0 URL Authorization

10.

(可选)在“描述”中键入关于 IIS URL Authorization 用法的信息。

11.

单击“确定”。

12.

在控制台树中,双击 Authorization Manager,双击 Authorization Manager,双击存储库名称,双击应用程序名称,双击“描述”,右键单击“操作定义”,然后单击“新建操作定义”。

13.

在“新建操作定义”的“名称”中键入 AccessURL,然后在“操作数目”中键入 1

为应用程序建立作用域

1.

在控制台树中,右键单击“IIS 6.0 URL Authorization”,并单击“新建作用域”。

2.

在“名称”中键入 WebApp,然后单击“确定”。

3.

在控制台树中,双击 IIS 6.0 URL Authorization,双击“定义”,右键单击“角色定义”,然后单击“新建角色定义”。

这一角色定义也可在 WebApp 作用域中进行创建。

4.

在“名称”中键入 Viewer(观察者),然后单击“确定”。

5.

在控制台树中,双击“角色定义”。

6.

在详细信息窗格中,右键单击 Viewer,然后单击“特性”。

7.

单击“定义”选项卡,单击“添加”,然后单击“操作”选项卡。

8.

选中“AccessURL”复选框,单击“确定”,接着再次单击“确定”。

9.

在控制台树中,转到“IIS 6.0 URL Authorization”,再转到“WebApp”,在其中右键单击“角色分配”,然后单击“分配角色”。

10.

选中 Viewer 复选框,然后单击“确定”。

11.

在详细信息窗格中,右键单击您在前面所创建的“角色分配”,然后单击“分配 Windows 用户和组”。

12.

在“输入所要选择的对象名(示例)”中键入您的用户名称,然后单击“确定”。

将 IIS 工作者进程添加到存储库的“读者”角色中

IIS 默认运行于网络服务(Network Service)帐户。您可以配置一个 IIS 工作者进程,使之在另一个帐户中运行。对于这个示例,我们将会把“网络服务”添加到“读者”角色中。

注意: 如果您使用一个远程授权存储库(例如:Active Directory 或一个基于存储的远程 XML 文件),并在默认的网络服务上下文中运行 IIS,那么运行 IIS 的 Web 服务器的 Active Directory 帐户就必须添加到存储库的“读者”角色中。

1.

如果还没打开 Authorization Manager MMC,请单击“启动”,单击“运行”,键入“Azman.msc”,然后按回车键。

2.

在控制台树中,右键单击 “授权管理器”,然后单击 “打开授权存储库”,单击“浏览”,单击 C:/MyStore.xml (在这个示例中,它是您想要使用的存储库),单击“确定”,然后再次单击“确定”。

3.

在控制台树中,右键单击存储库的名称,然后单击“特性”。

4.

单击“安全性”选项卡,在“授权管理器用户角色”列表中单击“读者”,然后单击“添加”。

5.

在“输入要选择的对象名称(示例)” 框中,键入“网络服务”,并单击“确定”,然后再次单击“确定”。

为 Web 应用程序配置 IIS 元库(Metabase)以使用 URL

1.

单击“启动”,单击“运行”,键入 Cmd,然后按回车键。

2.

使用上方提供的脚本来创建 SetUrlAuth.vbs 文件,并将文件保存在 /InetPub/AdminScripts 目录中。(InetPub 目录默认位于安装 IIS 的驱动器的根目录下。)

3.

键入以下命令并按回车键。

4.

CScript SetUrlAuth.vbs VDirPathAuthMgrScopeNameAuthMgrStoreNameEnabledImpersonationLevel

例如,您可以键入以下内容:

Cscript SetUrlAuth.vbs W3svc/1/Root/WebApp WebApp msxml://C:/MyStore.xml true 1

现在,IIS URL 授权就已配置完毕,并可对指定的 Web 应用程序运行。处于“观察者”角色的用户就可以定位到该应用程序的页面中了。

重要须知: 如果您使用的是 .xml 文件,则应加上 msxml:// 前缀;如果您使用 Active Directory Authorization Manager 存储库,则应加上 msldap:// 前缀。

返回页首返回页首

场景:Web 开支应用程序

在本场景中,一个基于 Web 的应用程序会采用以下程序。

1.

一个用户访问该开支应用程序的 URL ,并选择输入新的开支报告。

2.

该用户输入开支报告,并提交以待批准。

3.

经理收到一个电子邮件通知,告知他有一份开支报告有待批准。

4.

经理访问用于批准的 URL,后者可让经理检查并批准该开支报告或者将其驳回。

5.

如果经理批准了该开支报告,则该报告会被添加到一个验证队列中,在这里有一个验证程序可以检查该报告、收集收据、将开支报告标记为 “Approval-verified”(批准已核实),并请求一个补偿(reimbursement)。

注意:要想获得一个使用授权管理器的样本应用程序,请参阅 Microsoft Platform SDK 中的 MicrosoftSDKPath/Samples/Security/Authorization/AzMan。要想了解有关安装 Microsoft Platform SDK 的信息,请参阅 Microsoft Web 站点中的 http://www.microsoft.com/msdownload/platformsdk/sdkupdate/

操作

在上述开支应用程序场景中,操作可以被定义为:

ExecuteExpenseControls:运用这种控制可以让用户填写开支表单。

ExecuteApprovalControls:运用这种控制可以让用户批准开支。

RetrieveExpenseForm:从数据库中检索所请求的开支表单。

SaveExpenseForm:将开支表单保存到本地机器上。

EnqueApproval:将完成的表单副本放在批准队列中。

DequeApproval:从批准队列中删除开支。

SendRequestNotification:发送电子邮件给经理以请求批准。

SendApprovalNotification:发送批准的电子邮件通知。

ApproveDenyExpense:将开支标记为“批准”或“拒绝”。

VerifyApproval:将开支标记为“Approval-Verified”。

SetExpenseLimit:设置所能批准的角色种类上限。

FwdRembursment:发送消息给 Accounts Payable(支付帐户)。

ReadApprovals:读取批准队列中的开支表单。

ReadArchive:读取批准档案中的开支表单。

任务

在几个开支应用程序中,用户可能都需要用到上述一些操作。使用任务的应用程序必须将每项任务作为不需要有其他任务或操作权限的独立需求进行测试。

在开支应用程序场景中,可以有以下几种任务:

创建报告:填写开支报告的例程。相关操作:ExecuteExpenseControls、RetrieveExpenseForm、SaveExpenseForm。

提交报告:将开支报告上传到未决状态队列中,并发送电子邮件给经理的例程。相关操作:EnqueApproval、SendRequestNotification。

查看报告:显示未决报告的例程。相关操作:[Create Report] + AddApprovalQueue + SendNotification。

批准报告:促使报告从未决状态切换到批准状态,发送电子邮件给提交者并通知付款系统的例程。

检验批准:标记开支为 “Approval-Verified” 并将补偿请求转发到 Accounts Payable 所需要的操作。相关操作:ExecuteApprovalControls、ApproveExpense、SendApprovalNotification、FwdRembursment。

审核报告:允许读取批准队列和批准档案中的报告(ReadApprovals)

配置上限:允许设置雇员和经理的批准上限(SetExpenseLimit)

BizRules

在 Web 开支应用程序中,“批准报告”(Approve Report)任务必须附加以下 BizRule。

Dim Amount BizRuleContext.BusinessRuleResult = FALSE Amount = BizRuleContext.GetParameter("Amount") Limit = BizRuleContext.GetParameter(Limit) If Amount < Limit then BizRuleContext.BusinessRuleResult = true

要将以上 BizRule 附加到 Submit Report 任务中要求给定的开支比传递的开支上限小。应用程序会从开支报告中检索 Amount 参数,而 Limit 的值则由 Web 开支应用程序的管理员配置。

重要须知: 每个 BizRule 必须立即将 BusinessRuleResult 的值设置为 FALSE。要不如果由于代码错误或环境问题导致 BizRule 过早结束,则随机数据可能会将 BizRule 结果值指定为 TRUE,从而授权访问。

角色和角色定义

对于 Web 应用程序,在安装过程中会定义以下角色。

角色任务提交报告查看报告批准报告检验报告删除报告配置上限

用户

为他们自己提交报告

个人提交的这些报告

经理

为直接报告提交

由直接报告提交的

由直接报告提交的

检验程序

开支管理

所有报告

角色分配

角色分配由 Web 开支应用程序管理员在安装之后进行配置。管理员可使用的内容为:

用户: 用于所有雇员的 Windows Active Directory 组。

经理: 检查直接报告的标题和数量的 LDAP 组。

(&(Title = Manager)(numReports > 0)) 

Active Directory 模式必须进行扩展以便支持用户对象上的这些特性。这些特性由一个独立的人力资源应用程序进行维护。

检验程序: 一个应用程序基本组,列出检验开支的每个用户。

开支管理: 包含开支统计部分中的用户的 Active Directory 组。

运用以上的某一种技术创建一个 Authorization Manager 客户端上下文之后,Web 开支应用程序就会调用该客户端上下文接口中的 AzClientContext.GetRoles 方法来确定该用户分配了哪些角色。这样您就可以使用客户端角色成员资格来确定显示哪些选项给该用户。

如果用户处于“雇员”(Employee)角色,那么就会显示开支控制,可以让该用户提交开支。如果用户处于“经理”(Manager)角色,则显示页面还有另外一个区域,在这区域中显示已提交的未决开支表单列表。

将角色名称和应用程序逻辑紧密关联会造成管理员修改困难,所以应用程序必须使用一个约定,基于角色成员资格定制表达式。在这个示例中,“雇员”和“经理”角色并非硬编码到应用程序中,相反,角色名称与有类似名称的 HTML 文件相对应。另外,AzRole 对象的 ApplicationData 特性也可以用于对应用程序提供表达式信息。

当用户单击一个表单按钮来创建一个新的开支报告时,Web 开支应用程序就会调用 AccessCheck,发送对应于 ExecuteExpenseControlsRetrieveExpenseFormSaveExpenseForm 操作的操作值。这样做您就可以防止受限用户加载这些控制并降低性能。如果这个用户访问控制,则控制就会显示并从一个 SQL 存储检索开支表单并加载到控制中,于是就允许用户输入开支数据了。输入完成之后,用户单击 Submit 按钮,Web 开支应用程序就调用 AccessCheck,它指定提交一个开支需要的操作(例如,与 EnqueApproval 或 SendRequestNotification 相对应的操作数)。另外,随着一个 BizRule 参数调用 Amount,开支数目就被送入 AccessCheck。如果允许访问,则开支报告会被上传到未决请求的一个 SQL 队列中,并且发送一封电子邮件通知用户的经理有一个未决请求。

为了执行这些操作,几个后端资源需要具有一定的权限。包括在其中检索开支表单的 NTFS 目录、用于存储所提交的开支报告的 SQL 数据库以及一个用于发送电子邮件通知的 Web 开支 Microsoft Exchange 帐户。Web 开支服务帐户并不是像客户端那样模拟和执行操作,而是必须被授予足够的权限来访问在后端对象,以便执行应用程序需要的操作。因此,后端 DACL 只授权访问 Web 开支服务帐户。(要想了解更多信息,请参阅本文前面的 “受信任的子系统应用程序模型”。)

当一个经理看到上述的未决开支时,AccessCheck 会检验他是否具有使用批准控制的能力。然后这位经理浏览开支的详细资料并单击“批准” 或“拒绝”。以下的操作会调用 AccessCheckDequeApprovalApproveDenyExpenseSendRequestNotification。另外,AmountApprovingMgrSubmitter 参数会相应给出以下数值:所提交的开支的数量、尝试批准或拒绝这些开支的当前用户和提交开支者的名称。在 AccessCheck 的过程中,BizRule 会将调用用户当作提交用户的经理来检验,方法是为当前执行批准的经理检验 Exchange 或 SQL 中的联系,并检验数量是否属于当前指定的限定范围之内。

返回页首返回页首

场景:使用带有自定义主体的授权管理器

使用自定义主体或非 Windows 主体(例如:SQL、Passport、Microsoft Commerce Server 或 ADAM 主体)的应用程序可以利用大多数授权管理器的运行时特性。

不管是在 Active Directory 中,还是在 XML 中,授权管理器都会存储 SID,将其作为组或角色的成员,除了 LDAP 查询组(没有静态成员)。在添加一个 SID 到一个角色或一个应用程序组中时,并不会检验它是否是一个与 Active Directory 或 Windows NT 帐户相对应的 SID。您可以添加一个完全没有意义的 SID 作为一个角色或一个组的成员。当 IAzClientContext::AccessCheck 被调用时,客户端上下文中的 SID 会与授权管理器角色和组中的 SID 做比较,其中并不检验该 SID 是否是一个 Active Directory 帐户。如果一个客户端上下文有一个自定义的 SID,而一个角色也被分配到一个与之相同的自定义 SID,不管是直接分配的还是通过具有同样的自定义 SID 的应用程序组的方式分配,AccessCheck 函数都会去检查这个 SID 是否是带有所请求的操作的角色或组的一个成员,并将与角色相关联的权限授予分配该 SID 的客户端上下文。您可以在授权管理器中运用这种行为将自定义主体类型添加到角色或应用程序基本组中,具体做法是为每个自定义主体创建一个自定义 SID,并将该 SID 分配给恰当的角色或应用程序基本组。

文本形式的 SID 具有这样的结构: S-Version-AuthorityID-X-Y-Z,其中 Version 是 SID 版本号,AuthorityID 是该 SID 的发行者的安全性授权 ID,而 XYZ 是子授权值。(当前所有 SID 都属于版本 1。)SID 长度可变,因为 SID 中的子授权号可变。SID 可以有高达 SID_MAX_SUB_AUTHORITIES 个子授权号。(在 winnt.h 中定义为 15。)自定义 SID 使用 1 作为版本号,使用 SECURITY_RESOURCE_MANAGER_AUTHORITY 作为 AuthorityID 值,使用自定义值作为子授权号。

在创建自定义 SID 时,您必须为您的应用程序建立一个 SID 设计方案。例如,您必须有 S-1-9-AppInstanceGUID-UserGuid,其中 9 是资源管理器子授权号,而 AppInstanceGUIDUserGUID 都是各自分为四个子授权号。您也可以使用 S-1-9-AppInstanceGuid-UserRID,其中 UserRID 是该用户在应用程序实例中的惟一标识。要想获取生成 GUID 的样本代码,请参见 Microsoft Windows 软件开发工具包(SDK)。

一旦您创建了一个自定义 SID,您就可以使用 IAzRole 或 IAzApplicationGroup 接口的 AddMember 方法来将该 SID 添加到授权管理器角色或组中。

要想初始化一个带有自定义 SID 的客户端上下文,您可以调用 IAzApplication::InitializeClientContextFromSID,并以字符串形式指定一个自定义 SID。这样就会创建一个有效的客户端上下文,这适合于执行对该自定义主体的访问权限检验。在实际应用中,一个自定义主体经过验证以后,应用程序就会将通过验证的主体映射到一个自定义的 SID 上(它是事先为该主体创建的),并调用 InitializeClientContextFromSID 来获取一个授权管理器客户端上下文。当在该客户端上下文中调用 AccessCheck 时,会为授权管理器角色和组中的成员对这个 SID 进行评估。

自定义主体的缺陷

使用自定义主体会存在一些缺陷。

您不能够使用 LDAP 查询组。由于用户不在 Active Directory 中,拥有 LDAP 查询组并没有意义。

您不能够使用 Active Directory 组或本地机器组。

您不能够使用 Authorization Manager MMC 用户接口。由于用户接口在显示角色或组成员时检验的是用户 SID,所以管理员在用户接口中只能看到文本字符串的 SID,而无法看到用户名称。更重要的是,用户接口只能获取 SID,以 Object Picker 方式进入角色和应用程序组,这种方式只允许您提取有效帐户或组。

使用自定义主体

下图阐述了授权自定义主体的过程。

图 8:授权自定义主体。

图 8:授权自定义主体。
查看全尺寸图片。

1.

验证该自定义主体用户,然后将该自定义主体映射到一个授权管理器自定义 SID 中。

2.

使用 InitializeClientContextFromSID,并将 AZ_CLIENT_CONTEXT_SKIP_GROUP 标记作为 loptions 参数传递,通过这样就可以创建一个带自定义 SID 的客户端上下文了。

在这完成之后,您可以使用 AccessCheck 来检验该自定义主体是否经授权可在指定的作用域内执行指定的操作。

原创粉丝点击