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

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

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

作者:Dave McPherson(Microsoft Corporation)

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

使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤
 
本页内容
使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤 介绍
使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤 授权策略存储
使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤 应用程序管理
使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤 审核
使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤 应用程序设计过程
使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤 开发 Authorization Manager 应用程序
使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤 性能
使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤 特定于环境的设计事项
使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤 Internet Information Services 6.0 URL 授权
使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤 场景:Web 开支应用程序
使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤 场景:使用带有自定义主体的授权管理器

介绍

在 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 标识了角色、用户和权限之间的关系。在这个模型中,角色是授予权限的对象,而且给用户分派了角色。

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

图 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 对象之间的关系。

使用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 的应用程序时,它从存储库加载授权策略信息。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对多层应用程序进行基于角色的访问控制的步骤返回页首

应用程序管理

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

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

管理作用域

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

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

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

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

角色继承

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

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

图 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 运行时审核

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 存储库的变更作为一个整体进行审核。

使用Authorization Manager对多层应用程序进行基于角色的访问控制的步骤返回页首

应用程序设计过程

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

确定操作

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

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

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

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

图 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 安全性基础结构中增加了对一种新的受信任的子系统应用程序模型的支持。

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

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

 

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

权限管理

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

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

权限提取

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

在实践中,有时为了节省时间,管理员会授予过多的访问权限。受信任的子系统应用程序模型可以让管理员只