购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.1 代码安全性的含义

Web应用程序的安全性主要包括代码访问的安全性和基于角色的安全性。

一般来说,这两种安全性可以互相渗透,熟悉代码访问安全性的开发人员可以轻松使用基于角色的安全性,而熟悉基于角色的安全性的开发人员也可以轻松地使用代码访问的安全性。代码访问的安全性和基于角色的安全性都是用公共语言运行库提供的一个通用结构来实现的。

代码访问的安全性和基于角色的安全性使用相同的模型和结构,因此它们共享若干基础概念,包括安全权限、类型安全、安全策略、主体、身份验证、授权。

1.安全权限

公共语言运行库允许代码仅执行它有权执行的操作。运行库通过权限对象实现托管代码的强制限制。安全权限的主要用途如下:

(1)代码可以请求需要的权限,.NET框架安全系统确定是否允许这样的请求。一般来说,仅当代码的验证区域值得授予这些权限时,系统才会授予权限。代码接收到的权限不会比安全性设置所允许的权限要多。

(2)运行库根据某些条件来授予代码权限,这些条件包括代码标识的特性、请求的权限和代码的信任程度(由管理员设置的安全策略确定)。

(3)代码可要求其调用方具有特定权限。如果在代码上设置了对特定权限的请求,则使用此代码的所有代码也都必须拥有该权限才能运行。

调用方一般可能拥有三类权限,各类权限都有特定的用途:

①代码访问权限:表示对受保护资源的访问权或执行受保护操作的能力。

②标识权限:表示代码具有支持特定类型的标识的凭据。

③基于角色的安全权限:确定用户(或用户的代理)具有特定的身份。PrincipalPermission是唯一一个基于角色的安全权限。

运行库在很多命名空间中都具有内置权限类,此外,运行库还支持对设计和实现自定义权限类。

2.类型安全

类型安全又称为强类型,指不可以将原始类型强制的转换成另外一个目标类型,从而对这个转换后的原始类型进行目标类型上定义的操作。通俗点讲,类型安全指的是变量类型定义后,不能再转换到其他类型(非本类型或非本类型的子类型)。

类型安全和内存安全的关系非常紧密,类型安全的代码只允许访问授权可以访问的内存位置,例如不能从其他对象的私有字段读取值。在实时(Just In Time,JIT)编译期间,可选的验证过程检查要实时编译为本机代码的元数据和中间语言(Microsoft IntermediateLanguage,MSIL),以验证它们是否为类型安全。如果代码具有忽略验证的权限,则将跳过此检查过程。

对于托管代码来说,类型安全验证不是强制的,但类型安全在程序集隔离和安全性强制中起着至关重要的作用。如果代码是类型安全的,则公共语言运行库可以将程序集彼此间完全隔离。这种隔离有助于确保程序集之间不会产生负面影响,提高了应用程序的可靠性。即使类型安全组件的信任级别不同,它们也可以在同一过程中安全地执行。

如果代码为不安全的,则会出现副作用。例如运行库无法阻止非托管代码调用到本机(非托管)代码和执行恶意操作。所有非类型安全的代码必须通过传递的枚举成员(SkipVerification)授予(SecurityPermission)后才能运行。

3.安全策略

安全策略是一组可配置的规则,公共语言运行库在决定允许代码执行操作时遵循该策略。安全策略由管理员进行设置,并由运行库强制执行。运行库帮助我们确保代码只能访问或调用安全策略允许的资源或代码。

每当加载程序集时,运行库就使用安全策略确定授予程序集的权限。在检查了描述程序集标识的信息(称为证据)后,运行库使用安全策略决定代码的信任程度和由此授予程序集的权限。

4.主体

主体代表一个用户的标识和角色以及其拥有的用户操作。.NET框架中基于角色的安全性支持三种主体:一般主体、Windows主体和自定义主体。这里需要注意,一般主体独立于Windows用户和角色存在。

Windows主体表示Windows用户及其角色。Windows主体可模拟其他用户,这意味着此类主体在表示属于某一用户标识的同时,可代表此用户对资源进行访问。

自定义主体可由应用程序以任何方式进行定义,这种类型可以对主体的标识和角色进行扩展。

5.身份验证

身份验证检查用户的凭据,并根据用户的权限进行验证,找到主体标识。身份验证期间获得的信息可以直接由代码使用。也就是说,一旦找到了主体标识,就可以使用.NET框架中基于角色的安全确定是否允许主体访问代码。

目前使用的身份验证机制种类繁多,其中大多都同.NET框架中基于角色的安全一起使用。最常用的机制有Passport机制、操作系统机制和应用程序自定义机制。

6.授权

授权是用来确定是否允许主体执行请求操作的过程。在身份验证之后,使用主体标识和角色信息来确定可以访问的资源,授权使用.NET框架中基于角色的安全性来实现。

介绍了代码访问安全性和基于角色的安全性共有的基本概念后,下面对这两种安全性的机制进行具体介绍。

1.1.1 代码与代码的安全域

1.概述

当今高度连接的计算机系统会遇到出自各种来源(可能包括未知来源)的代码。代码可能由电子邮件附带、包含在文档中或通过Internet下载。许多计算机用户都亲身体验过恶意代码(包括病毒和蠕虫)造成的严重后果,这些代码可能会损坏或毁坏数据,并浪费时间和资金。

多数普通安全机制根据用户的登录凭据(通常为密码)赋予用户权限,并限制允许用户访问的资源(通常为目录和文件)。但是,这种方法无法解决以下几个问题:用户从许多来源获取代码,这些来源中可能并不可靠;代码可能包含bug或具有脆弱性,有可能被恶意代码利用;代码有时候会执行一些操作,而用户并不知道。结果,当谨慎且可信的用户运行恶意软件或包含错误的软件时,计算机系统就可能会损坏,私有数据发生泄漏。

多数操作系统安全机制要求每一段代码都必须完全受信任(Web页的脚本可能除外),然后才可运行。因此,需要一种可广泛应用的安全机制,即使两个计算机系统之间没有信任关系,该机制也允许在一个计算机系统上生成的代码能够在另一个计算机系统上安全执行。

为了帮助保护计算机系统免受恶意移动代码的危害,让来源不明的代码安全运行,防止受信任的代码有意或无意地危害安全,.NET框架提供了一种称为“代码访问安全性”的安全机制。代码访问安全性使代码可以根据它所来自的位置以及代码标识,获得不同等级的受信度。

代码访问安全性还实施不同级别的代码信任,最大限度地减少了必须完全信任才能运行的代码数量。使用代码访问安全性,可以减小恶意代码或包含错误的代码滥用代码的可能性。我们可以指定允许代码执行的一组操作,同时还可指定永远不允许代码执行的一组操作。代码访问安全性有助于最大限度地减少由于代码的脆弱性而造成的损害。

以公共语言运行库为目标的托管代码都会受益于代码访问安全性,即使托管代码不进行一次代码访问安全性调用时也是如此。但是,正如代码访问安全性基础知识中所描述的那样,所有应用程序都应该进行代码访问请求。

代码访问安全性是帮助限制代码对受保护的资源和操作的访问权限的机制。在.NET框架中,代码访问安全性执行下列功能:

(1)定义权限和权限集,它们表示访问各种系统资源的权限。

(2)管理员能够通过将权限集与代码组关联来配置安全策略。

(3)代码能够请求运行所需权限,指定代码不能拥有的权限。

(4)根据代码请求的权限和安全策略允许的操作,向加载的程序集授予权限。

(5)使代码能够要求其调用方拥有特定的权限。

(6)使代码能够要求其调用方拥有数字签名,只允许特定组织或特定站点的调用方调用受保护的代码。

(7)比较调用堆栈上每个调用方所授予的权限与调用方必须拥有的权限,加强运行时对代码的限制。

为了确定是否已授予代码访问资源或执行操作的权限,运行库的安全系统遍历调用堆栈,比较每个调用方所授予的权限与目前要求的权限。如果调用堆栈中的任何调用方没有要求权限,则会引发安全性异常,并拒绝访问。堆栈旨在防止引诱攻击,这种攻击中,受信程度较低的代码调用高度信任的代码,并使用高度信任的代码执行未经授权的操作。运行时要求所有调用方都拥有权限会影响性能,但对于帮助保护代码免遭受信程度较低的代码的引诱攻击至关重要。若要优化性能,可以使代码执行较少的堆栈步;但是,这样做必须确保不会暴露安全缺陷。

图1-1所示为“程序集A4”中的方法要求其调用方拥有权限P时引起的堆栈步。

图1-1 安全堆栈步

代码访问安全性的一种常见应用场合是,应用程序将控件从本地Intranet宿主网站直接下载到客户端,用户在控件输入数据,该控件是使用安装的类库生成的。下面是在此方案中使用代码访问安全性的一些方法。

(1)加载前,如果代码拥有特定的数字签名,则管理员可配置安全策略,指定给予该代码特殊权限(比本地Internet代码通常收到的权限大)。默认情况下,预定义的LocalIntranet命名权限集与从本地Intranet下载的所有代码关联。

(2)加载时,除非控件拥有受信任的签名,否则,运行库仅授予控件与LocalIntranet命名权限集关联的权限。在控件拥有受信任签名的情况下,会被授予与LocalIntranet权限集关联的权限,同时因为控件拥有受信任签名,还可能被授予其他一些权限。

(3)运行时,每当调用方(在此情况下为寄宿的控件)访问公开受保护资源的库或调用非托管代码的库时,该库就会提出安全要求,导致对调用方的权限进行检查,看调用方是否被授予了适当权限。这些安全检查可防止控件在客户端执行未经授权的操作。

2.基础知识

每种以公共语言运行库为目标的应用程序必须与运行库的安全系统进行交互。当应用程序执行时,运行库将自动进行计算,然后给出一个权限集。根据应用程序获得的权限不同,应用程序或正常运行,或发生安全性异常。特定计算机上的本地安全设置最终决定代码所收到的权限。这些设置可能因计算机而异,所以无法确保代码将收到运行所需的足够的权限。这与非托管开发领域不同,在非托管开发领域,不必担心运行代码所需权限。

每个开发人员都必须熟悉下面的代码访问安全性操作:

(1)编写类型安全代码:若要使代码受益于代码访问安全性,必须使用生成可验证为类型安全代码的编译器。

(2)强制性语法和声明式语法:与运行库安全系统的交互使用强制性安全调用和声明式安全调用执行。声明式调用使用属性执行,强制性调用在代码中使用类的新实例执行。有些调用只能强制性地执行,而有些调用只能以声明方式执行。有些调用可以这两种方式中的任一种方式执行。

(3)为代码请求权限:请求将应用到程序集范围,代码通知运行库在此范围内运行它所需的权限,运行库在代码加载到内存中时计算安全请求。代码使用请求通知运行库运行所需权限。

(4)使用安全类库:类库使用代码访问安全性指定所需权限。

3.通过部分受信任的代码使用类库

系统一般不允许通过低于完全信任级别(该信任级别是运行库代码访问安全系统授予的)的应用程序调用共享托管库,除非库编写器通过使用AllowPartiallyTrustedCallers Attribute类明确允许调用。因此,应用程序编写器必须注意在部分受信任的上下文中不能使用的库。默认情况下,在本地Intranet或Internet区域中执行的所有代码都是部分受信任的。如果代码不会在部分受信任的上下文中执行或被部分受信任的代码调用,那么就不需要关心本节中的信息。但是,如果编写的代码必须与部分受信任的代码交互或在部分受信任的上下文中运行,则应该考虑以下因素:

(1)必须用强名称对库进行签名,这样该库就可以被多个应用程序共享。强名称允许代码放置在全局程序集缓存中,并允许使用者验证特定的移动代码。

(2)默认情况下,具有强名称的共享库自动为完全信任执行隐式连接请求(LinkDemand),无须库编写器执行任何操作。

(3)如果调用方不是完全信任却仍尝试调用库,则运行库将引发安全处理程序SecurityException,不允许该调用方链接到该库。

(4)为了禁用自动连接功能并防止引发异常,可以将程序的局部信任属性放置在共享库的程序集范围内,此属性允许通过部分受信任的托管代码调用库。

(5)通过部分信任属性被授予对库访问权限的部分信任的代码仍需要遵循本地计算机策略定义的进一步限制。

(6)部分受信任的代码无法通过编程方式调用不具备AllowPartiallyTrustedCallers Attribute属性的库。如果某个应用程序在默认情况下不接受完全信任,管理员必须选择修改安全策略并授予该应用程序完全信任,这样的话,应用程序才能调用该库。

特定应用程序专用库不需要强名称或AllowPartiallyTrustedCallersAttribute属性,这些库也不能被应用程序之外的潜在恶意代码引用。这样的代码不会受到部分受信任的移动代码有意或无意的滥用,无需开发人员或管理员进行额外操作。

对于以下类型的代码,应该考虑显式启用以供部分受信任的代码使用:

(1)已对安全脆弱性进行反复测试并且符合安全代码指南中所述准则的代码。

(2)专门为部分受信任的方案编写的具有强名称的代码库。

(3)签有强名称的任何组件(不管是部分受信任的还是完全受信任的),这些组件被从Internet或本地Intranet下载的移动代码调用。在默认安全策略下移动代码接受部分信任,所以这些组件将受到影响。

(4)安全策略授予低于完全信任的所有代码(如果修改了默认策略)。

4.编写安全类库

类库中的编程失误会导致安全漏洞的公开,这是因为类库经常访问受保护的资源和非托管代码。如果设计类库,则需要了解代码访问安全性,并仔细保护类库。

表1-1所示为保护类库时需要考虑的3种主要元素。

表1-1 类库保护元素

5.编写安全托管控件

托管控件是下载到用户计算机的网页所引用的程序集,这些程序集根据需要执行。从代码访问安全性角度来看,有两种类型的托管控件:默认安全策略下运行的控件和需要更高信任程度的控件。

若要编写在默认安全策略下运行的托管控件,只需要知道Intranet或Internet区域默认安全策略所允许的操作即可。只要托管控件在执行时需要的权限不超过它从原始区域收到的权限,该控件就可以运行(记住,管理员或用户可以决定不授予代码来自Internet或Intranet区域的全部权限)。若要执行,则需要更高程度信任的托管控件,管理员或用户必须调整将运行该代码的任何计算机的安全策略。

编写托管控件时应尽可能使这些控件需要默认情况下授予代码来自Internet或Intranet区域的权限。对于Internet区域,这意味着限制代码只显示SafeTopLevelWindows和SafeSubWindows(由安全系统加以完善,从而防止它们模拟系统对话框),只能与其原始站点进行通信,并且使用有限的、独立的存储。

担负Intranet上的代码的权限稍大一些。详细信息参见默认安全策略相关内容。如果控件需要访问文件、使用数据库以及收集有关客户端计算机的信息等,则该控件需要更高程度的信任。

1)开发

高度信任控件在运行时采用的安全策略比它们的源(Intranet或Internet)通常认可的安全策略的限制性要低。安全库(如.NET Framework类)发出的多数权限要求执行堆栈审核来检查所有调用方,以确保已授予它们要求的权限;同时,出于安全目的,尽管网页不是托管代码,但仍被作为调用方处理。执行堆栈审核技术是为了帮助防止受信程度较低的代码引诱高度信任代码执行恶意操作。

浏览器中承载的托管控件可以由网页上的动态脚本操作,所以可以将网页视为调用方,并在安全堆栈审核技术中对其进行检查,防止恶意网页利用信任程度更高的代码。将网页作为调用方处理的结果是,基于其强名称或发行者证书而被授予高级别信任并且从网页运行的控件,将被禁止执行与网页本身出自同一区域(Intranet或Internet)的代码所执行的操作。有关部署注意事项的更多信息,请参见1.1.2节。从表面上看,几乎不可能编写高度信任控件;但是,代码访问安全性通过有选择地重写安全堆栈审核技术提供实现此方案。

高度信任控件必须明智地使用Asserts来简化对它们的调用方(它们从中运行的网页)通常没有的权限执行的堆栈审核技术。使用Asserts时必须小心,不要公开可能会使恶意网页执行不当操作的危险API。在编写高度信任控件时需要的谨慎程度和安全意识与编写安全类库时需要的谨慎程度和安全意识一样多。

下面是有关编写安全托管控件的一些提示:

2)部署

高度信任控件应当具有强名称或签有发行者证书(X.509),使得策略管理员可以将更高程度信任授予这些控件,而不会削弱它们在其他Intranet/Internet代码方面的安全性。对程序集签名后,用户必须创建关联有足够权限的新代码组,并指定只允许拥有用户的公司或组织签名的代码成为该代码组成员。以此方式修改安全策略后,高度信任控件将收到足够的权限来执行操作。

修改安全策略后,高度信任的控件才能正常运行,所以在企业的Intranet上部署这种类型的控件要容易得多,企业的Intranet通常设有企业管理员,管理员可将描述的策略更改部署到多个客户端计算机上。为了让没有共同组织关系的一般用户通过Internet使用高度信任控件,控件发行者和用户之间必须有一种信任关系。最终,用户必须愿意使用发行者的说明来修改策略,并允许高度信任控件执行。

6.创建自定义代码访问权限类

.NET框架提供了一组代码访问权限类,保护一组特定的资源和操作,并重点保护由.NET框架公开的那些资源。在权限主题中对这些类进行了概括描述,在每个权限类的文档中提供对该权限类的详细描述。对于多数环境,内置的代码访问权限已经够用。但在某些情况下,定义自己的代码访问权限类可能会有用。此主题讨论定义自定义代码访问权限类的场合、原因和方式。

如果要定义一个组件或类库,该组件或类库访问内置权限类未涵盖但需要避免未经授权的代码访问的资源,则应当考虑创建一个自定义代码访问权限类。如果希望对自定义权限发出声明式要求,还必须为该权限定义一个Attribute类。提供这些类并从类库内发出对该权限的要求,可以防止未经授权的代码访问相应的资源,并使管理员能够配置访问权限。

还有其他一些情况适合使用自定义权限。如果内置代码访问权限类保护一种资源但不能充分控制对该资源的访问,则需要使用自定义代码访问权限。例如,一种应用程序可能使用人事记录,每个职员的记录存储在一个单独的文件中;在这种情况下,可以独立地对不同类型的职员数据进行读写控制。应用程序可能授权内部管理工具读取某个职员的人事文件,但不允许该工具修改这些文件。事实上,甚至可能不允许该工具读取某些部分。

自定义代码访问权限还适用于这种情况:内置权限虽然存在,但其定义方式不能使之恰当地保护资源。例如,对一种UI功能(如创建菜单的功能)必须进行保护,但内置的UIPermission类却不提供保护。在这种情况下,可以创建一种自定义权限来保护创建菜单的功能。

只要可能,权限就不应重叠。拥有多个权限保护一种资源会给管理员带来很大的问题:管理员在每次配置访问该资源的权限时,都必须确保正确地处理所有重叠的权限。

实现自定义代码访问权限包括下列步骤,其中的一些步骤是可选的。每个步骤在一个单独主题中进行描述。

(1)设计Permission类。

(2)实现IPermission和IUnrestrictedPermission接口。

(3)实现ISerializable接口(如果性能需要,或者为了支持特殊的数据类型)。

(4)处理XML编码和解码。

(5)通过实现Attribute类添加声明式安全支持。

(6)在适当的时候请求自定义权限。

(7)更新安全策略以便识别自定义权限。

1.1.2 代码的安全策略

商务应用程序需要根据用户提供的凭据开放对数据或资源的访问权限。通常情况下,这种应用程序会检查用户的角色,并根据该角色提供对相应资源的访问。公共语言运行库根据Windows账户或自定义标识提供基于角色的授权支持。

1.概述

在财务或商务应用程序中经常使用角色限制策略。例如,应用程序可能根据提出请求的用户是不是指定角色的成员,对要处理的事务大小加以限制。职员有权处理的事务可能小于指定的阈值,主管拥有的权限可能比职员的高,而副总裁的权限可能还更高(或根本不受限制)。当应用程序需要多个批准完成某项操作时,也可以使用基于角色的安全性。例如,在一个采购系统中,任何雇员均可生成采购请求,但只有采购代理人可以将此请求转换成可发送给供应商的采购订单。

.NET框架基于角色的安全性通过生成可供当前线程使用的主体信息来支持授权,而主体是用关联的标识构造的。标识(及其帮助定义的主体)可以基于Windows账户,也可以是同Windows账户无关的自定义标识。.NET框架应用程序可以根据主体的标识或角色成员条件(或两者)做出授权决定。角色是指在安全性方面具有相同特权的一组命名主体(如出纳或经理)。一个主体可以是一个或多个角色的成员。因此,应用程序可以使用角色成员条件来确定主体是否有权执行某项请求的操作。

为了使权限控制代码易于使用并与.NET语言保持一致性,.NET框架基于角色的安全性提供了PrincipalPermission对象,此对象使公共语言运行库能够按照与代码访问安全性检查类似的方式执行授权。PrincipalPermission类表示主体必须匹配的标识或角色,并同声明式和命令性安全检查都兼容。也可以直接访问主体的标识信息,并在需要时在代码中执行角色和标识检查。

.NET框架提供了灵活且可扩展的基于角色的安全性支持,足以满足广泛的应用程序的需要。可选择同现有的身份验证结构(如COM+1.0服务)相互操作,或创建自定义身份验证系统。基于角色的安全性尤其适用于主要在服务器处理的ASP.NET Web应用程序。不过,.NET框架基于角色的安全性既可用于客户端,也可用于服务器。

2.主体和标识对象

托管代码可通过Principal对象发现主体的标识或角色,该对象包含对Identity对象的引用。将标识和主体对象同用户与组账户这样常见的概念进行比较,可能会有所帮助。在多数网络环境中,用户账户表示人员或程序,而组账户表示特定类别的用户及其拥有的权限。同样,.NET框架中的标识对象表示用户,而角色表示成员条件与安全性上下文。在.NET框架中,主体对象同时封装标识对象和角色。.NET框架应用程序根据主体的标识或角色成员条件(后者更常见)向主体授予权限。

1)标识对象

标识对象封装有关正在验证的用户或实体的信息。在最基本的级别上,标识对象包含名称和身份验证类型。名称可以是用户名或Windows账户名,而身份验证类型可以是所支持的登录协议(如Kerberos V5)或自定义值。.NET框架定义了一个GenericIdentity对象和一个更专用的WindowsIdentity对象,前者可用于大多数自定义登录方案;后者可用于希望应用程序依赖Windows身份验证的情况。此外,还可以定义自己的标识类来封装自定义用户信息。

IIdentity接口定义用于访问名称和身份验证类型(如Kerberos V5或NTLM)的属性。所有Identity类均实现IIdentity接口。Identity对象同执行当前线程所用的Windows进程标记之间不需要有什么关系。但是,如果Identity对象是WindowsIdentity对象,则假定标识表示安全标记。

2)主体对象

主体对象表示代码运行时所在的安全上下文。实现基于角色的安全性的应用程序将基于与主体对象关联的角色来授予权限。与标识对象相似,.NET框架也提供了GenericPrincipal对象和WindowsPrincipal对象。您还可以定义自己的自定义主体类。

IPrincipal接口定义一个属性和一个方法,前者用于访问关联的Identity对象;后者用于确定Principal对象所标识的用户是否为给定角色的成员。所有Principal类都实现IPrincipal接口以及任何必需的附加属性和方法。例如,公共语言运行库提供了WindowsPrincipal类,该类实现将Windows Vista或Windows 7组成员条件映射到角色的附加功能。

Principal对象将被绑定到应用程序域(AppDomain)内部的调用上下文(CallContext)对象。默认的调用上下文总是用每个新的AppDomain创建的,因此总是存在可用于接受Principal对象的调用上下文。创建新线程的同时也为该线程创建CallContext对象。Principal对象引用从创建线程自动复制到新线程的CallContext中。如果运行库无法确定哪个Principal对象属于线程的创建者,将遵循Principal和Identity对象创建的默认策略。

可配置的应用程序域特定策略定义了一些规则,用以决定同新的应用程序域关联的Principal对象类型。在安全策略的允许范围内,运行库可创建Principal和Identity对象来反射同当前执行线程关联的操作系统标记。默认情况下,运行库使用Principal和Identity对象表示未经身份验证的用户。运行库不创建这些默认的Principal和Identity对象,除非代码试图访问它们。

创建应用程序域的受信任代码可设置应用程序域策略,以控制默认Principal和Identity对象的构造。此应用程序域特定的策略适用于该应用程序域中的所有执行线程。非托管的受信任宿主本身就具有设置此策略的能力,但托管代码必须具有控制域策略的System.Security.Permissions.SecurityPermission才能设置此策略。

在不同的应用程序域之间、但在同一进程内(因此在同一台计算机上)传输Principal对象时,远程基础结构将同调用方上下文相关联的、对Principal对象的引用复制到被调用方的上下文中。

3.PrincipalPermission对象

基于角色的安全性模型支持与代码访问安全性模型中的权限对象类似的权限对象。此对象(即PrincipalPermission)表示特定主体类在运行时必须具有的标识和角色。以命令方式和声明方式进行的安全检查均可使用PrincipalPermission类。

若要以命令方式实现PrincipalPermission类,请创建该类的一个新实例,并用希望用户在访问代码时具有的名称和角色来初始化该实例。例如,以下代码以'Joan'身份和'Teller'角色对此对象的一个新实例进行初始化。

可使用PrincipalPermissionAttribute类以声明方式创建一个类似的权限。以下代码以声明方式将身份初始化为Joan,并将角色初始化为Teller。

执行安全检查时,为成功完成检查,指定的身份和角色必须匹配。但是,创建PrincipalPermission对象时,可传递一个null身份字符串以指示主体的身份可以是任意的。同样,传递一个null角色字符串指示主体可以是任何角色的成员(或根本不属于任何角色)。对于声明的安全性,可通过省略两种属性中的一个来获得相同的效果。例如,下列代码使用PrincipalPermissionAttribute以声明方式指示主体可以具有任意名称,但必须具有出纳的角色。

4.基于角色的安全检查

定义了标识和主体对象后,可采用下列方法之一对其进行安全检查:

托管代码可使用命令式或声明式安全检查来确定以下内容:特定主体对象是否是已知角色的成员,是否具有已知的身份,或是否表示一种角色中的一个已知身份。若要通过命令式或声明式安全性进行安全检查,必须对适当构造的PrincipalPermission对象生成一个安全请求。安全检查期间,公共语言运行库检查调用方的主体对象,确定其身份和角色是否与所请求的PrincipalPermission表示的身份和角色相匹配。如果主体对象不匹配,则将引发SecurityException。只检查当前线程的主体对象,PrincipalPermission类不会像代码访问权限那样导致产生堆栈遍历。

此外,可以直接访问主体对象的值,并在不使用PrincipalPermission对象的情况下执行检查。在这种情况下,只需读取当前线程主体的值或使用IsInRole方法执行身份验证。

5.同COM+1.0安全性相互操作

可以使用新的.NET框架托管组件来扩展现有的COM+1.0应用程序。COM+1.0安全性上下文仍由COM+1.0托管,而COM+1.0管理用户界面用于配置应用程序。从COM+1.0应用程序看,.NET框架对象基本上类似于COM+1.0对象。

若要使.NET框架对象对COM+1.0安全服务可见,必须运行由Windows软件开发工具包(SDK)提供的工具(如Tlbexp.exe),以便为公共接口生成类型库并注册这些对象,以使COM+1.0可以定位它们。COM+1.0管理功能必须用于配置角色以及其他基于角色的安全行为。

与COM+1.0安全性的相互操作有一些局限性。COM+1.0安全属性不在进程间或计算机边界之间传播,也不传播到托管代码中新创建的执行线程。COM+1.0安全服务只能在Windows Vista系统上由托管代码使用。

.NET框架在System.EnterpriseServices命名空间中提供了若干个允许对COM+1.0安全功能进行访问的托管包装。 NNzzXnGqTfYPVXnkVfAHk9HJyWj6oNqWkcGTyiFSUep6EyWbVDVxUGaDwC+4iKoS

点击中间区域
呼出菜单
上一章
目录
下一章
×