编写安全托管控件
更新:2007 年 11 月
托管控件是下载到用户的计算机的网页引用的程序集,这些程序集根据需要来执行。从代码访问安全性角度来看,有两种类型的托管控件:在默认的安全策略下运行的控件和需要更高程度信任的控件。
若要编写旨在默认安全策略下运行的托管控件,则只需要知道对于 Intranet 或 Internet 区域默认安全策略所允许的操作即可。只要托管控件在执行时需要的权限不超过它从原始区域收到的权限,该控件就可以运行。(记住,管理员或用户可以决定不将来自 Internet 或 Intranet 区域的权限全部授予代码。)若要执行需要更高程度信任的托管控件,管理员或用户必须调整将运行该代码的任何计算机的安全策略。
编写托管控件时应尽可能使这些控件不需要默认情况下未授予 Internet 或 Intranet 代码的权限。对于 Internet 区域,这意味着限制代码只显示 SafeTopLevelWindows 和 SafeSubWindows(由安全系统加以完善,从而防止它们模拟系统对话框),只能往回与其原始站点进行通信,并且使用有限的、独立存储。
Intranet 上的代码的权限稍大一些。有关全部详细信息,请参见默认安全策略。如果您的控件需要访问文件,使用数据库,收集有关客户端计算机的信息等,则该控件需要更高程度的信任。
开发
高度信任控件预期在运行时采用的安全策略比它们的源(Intranet 或 Internet)通常认可的安全策略的限制性要低。安全库(如 .NET Framework 类)发出的多数权限要求执行堆栈审核来检查所有调用方,以确保已授予它们要求的权限;同时,出于安全目的,尽管网页不是托管代码,仍被作为调用方处理。执行堆栈步是为了帮助防止受信程度较低的代码引诱高度信任代码执行恶意操作。
因为浏览器中承载的托管控件可以由网页上的动态脚本来操作,所以会将网页视为调用方,并在安全堆栈步中对其进行检查,以帮助防止恶意网页作者利用信任程度更高的代码。将网页作为调用方处理的结果是,基于其强名称或发行者证书而被授予高级别信任并且从网页运行的控件,将被禁止执行通常不允许那些与网页本身出自同一区域(Intranet 或 Internet)的代码执行的操作。有关部署注意事项的更多信息,请参见下一节。表面上来看,这使得似乎不可能编写高度信任控件;但是,代码访问安全性通过使您可以有选择地重写安全堆栈步行为来提供实现此方案的方法。
高度信任控件必须明智地使用 Asserts 来简化对它们的调用方(它们从中运行的网页)通常没有的权限执行的堆栈步。使用 Asserts 时必须小心,不要公开可能会使恶意网页执行不当操作的危险 API。因此,在编写高度信任控件时需要的谨慎程度和安全意识与编写安全类库时需要的谨慎程度和安全意识相近。
下面是有关编写安全托管控件的一些提示:
如果可能,封装需要高度信任的操作,使它们不会被控件公开。这样,您可以断言这些操作需要的权限,并且可以相信,使用您的控件的网页将无法滥用相应的功能。
如果控件的设计需要公开它执行的高度信任操作,请考虑发出一个站点或 URL 标识权限要求,以确保只能由您打算让控件从其运行的网页调用控件。
部署
高度信任控件应当总是具有强名称或签有发行者证书 (X.509)。这使得策略管理员可以将更高程度信任授予这些控件,而不会削弱它们在其他 Intranet/Internet 代码方面的安全性。对程序集签名后,用户必须创建关联有足够权限的新代码组,并指定只允许用户的公司或组织签名的代码成为该代码组的成员。以此方式修改安全策略后,高度信任控件将收到足够的权限以便执行。
因为必须修改安全策略,才能使高度信任、下载的控件正常运行,所以在企业的 Intranet 上部署这种类型的控件要容易得多,企业的 Intranet 通常有企业管理员,管理员可将描述的策略更改部署到多个客户端计算机上。为了让没有共同的企业或组织关系的一般用户通过 Internet 使用高度信任控件,控件发行者和用户之间必须有一种信任关系。最终,用户必须愿意使用发行者的说明来修改策略,并允许高度信任控件执行。否则,将不允许控件运行。