asp.net|程序
本单元概要
Microsoft ® Windows ® Server 2000 和 Windows Server ™ 2003 操作系统提供了伸缩性非常好、非常可靠的 Web 宿主环境。它们可以用于在一个 Web 服务器或者 Web 服务器场上安全地寄宿成百上千个 Web 站点和 ASP.NET 应用程序。
但是,当在共享宿主场景中使用 ASP.NET 应用程序时,必须考虑如何使应用程序互相独立,以及独立于共享系统资源,包括文件系统、注册表和事件日志。没有足够的独立性,恶意或者设计不良的应用程序会对服务器上的其他应用程序产生负面影响,或者访问未授权的资源。这种应用程序独立对于寄宿多家不同公司的大量应用程序的 Internet 服务提供商 (ISP) 尤其重要。
本单元阐述了在 Windows 2000 和 2003 中可以使用哪些技术隔离 ASP.NET 应用程序,以确保所寄宿的 Web 站点数据的完整性、保密性和真实性。
返回页首
目标
通过本单元能够:
• 理解 Windows 2000 和 2003 中 ASP.NET 的体系结构和主要组成部分。
• 使用多个标识、应用程序池和代码访问安全隔离 Web 应用程序。
• 配置匿名帐户模拟。
• 在使用集成 Windows 身份验证或者证书对用户进行身份验证时,配置固定的帐户模拟以访问本地或者远程的资源。
• 提高窗体身份验证的安全性。
• 理解在访问 UNC 共享中存储的数据时,如何使用凭据。
返回页首
应用范围
本单元适用于下列产品和技术:
• Microsoft Windows Server 2000 和 2003
• Microsoft .NET Framework 1.1 和 ASP.NET 1.1
返回页首
如何使用本单元
本单元主要关注如何获得共享宿主环境中的应用程序独立。关键的要素是代码访问安全。在使用本单元的同时还应该结合以下内容:
• 阅读单元 8“代码访问安全实践”。该单元更详细地解释了代码访问安全的工作原理,以及如何使用它约束单独的程序集,例如限制程序集访问文件系统、注册表、网络和其他关键资源的能力。
• 阅读单元 9“在 ASP.NET 中使用代码访问安全”。该单元解释了如何将代码访问安全策略用于 ASP.NET 应用程序,并讨论了构建部分信任应用程序的注意事项和意义。
• 阅读单元 16“保护 Web 服务器的安全”。该单元说明了如何保护 Windows 2000 操作系统和 Microsoft .NET Framework。安全的基础平台是保护一个 ASP.NET Web 应用程序或者 Web 服务的前提条件。
本页内容
本单元概要
目标
应用范围
如何使用本单元
简介
Windows 2000 上的 ASP.NET 体系结构
Windows Server 2003 上的 ASP.NET 体系结构
用标识隔离应用程序
用应用程序池隔离应用程序
用代码访问安全隔离应用程序
窗体身份验证的问题
UNC 共享寄宿
小结
返回页首
简介
在共享宿主场景中,确保应用程序不会对其他应用程序的操作和安全产生负面影响,是非常重要的。
获得应用程序独立有许多方式。可用的选择因 Web 服务器上运行的 .NET Framework 的版本和操作系统的版本的不同而不同。
• 如果运行的是 .NET Framework 的 1.1 版本,可以使用代码访问安全提供的资源约束模型提供一层应用程序独立。这种应用程序独立是通过限制应用程序访问不同类型的资源(如文件系统、注册表、事件日志、Active Directory、数据库、网络资源等等)而实现的。
• Windows Server 2003 通过 Internet 信息服务 6.0 (IIS 6) 应用程序池提供了进程独立,可以使多个应用程序运行在不同的 IIS 辅助进程实例中。进程独立在 Windows 2000 上是不可能的,因为所有 Web 应用程序都运行在单独的 ASP.NET 辅助进程实例中,而应用程序域提供了独立性。
表 1 总结了 Windows 2000 和 Windows Server 2003 上应用程序独立的各种选择。
表 1 Windows 2000 和 Windows Server 2003 上的应用程序独立功能
独立功能 Windows 2000 Windows Server 2003
进程独立
否
是(IIS 6 应用程序池)
应用程序域独立
是
是
多个线程标识
是
是
代码访问安全资源约束
是(.NET Framework 1.1 版)
是(.NET Framework 1.1 版)
运行着 .NET Framework 1.1 版的 Windows Server 2003 是寄宿多个 ASP.NET 应用程序的推荐平台,因为它支持进程独立,并为应用程序独立提供了最大范围的选择。
返回页首
Windows 2000 上的 ASP.NET 体系结构
在 Windows 2000 上,多个 Web 应用程序运行在一个 ASP.NET 辅助进程 (Aspnet_wp.exe) 实例中。每个应用程序都驻留在自己的应用程序域中,为托管代码提供了一定程度的独立性。Windows 2000/IIS 5 体系结构如图 1 所示。
图 1. 带有 IIS 5 的 Windows 2000 上的 ASP.NET 体系结构
表 2 总结了图 1 中所描述的体系结构的组成部分
表 2 Windows 2000 ASP.NET 体系结构组成部分 | |
组成部分 | 说明 |
Inetinfo.exe | 主 IIS 进程。运行在本地 SYSTEM 帐户下的 Windows 服务。 |
Aspnet_isapi.dll | IIS 脚本映射将 ASP.NET 文件类型和运行在 Inetinfo.exe 内的该 ASP.NET 的 ISAPI 扩展关联起来。 它负责将请求通过异步命名管道转发给 ASP.NET 辅助进程。它还启动了辅助进程并执行运行状况监控。ISAPI 扩展不包含托管代码,本身也并不执行请求处理。 |
Aspnet_filter.dll | 一个轻型的 ISAPI 筛选器,仅用于支持 ASP.NET应用程序的无 cookie 的会话状态。Aspnet_filter.dll 运行在 Inetinfo.exe 内。 |
Aspnet_wp.exe | ASP.NET 辅助进程。在不同的应用程序域(用于提供独立)中寄宿多个 Web 应用程序。通常每个服务器一个实例,虽然在多处理器服务器上,Web 园模式支持带有给定处理器关系的多个相同的进程。不可能将多个特定 Web应用程序分隔到不同的进程中。要求用 IIS 6 和 Windows Server 2003。Aspnet_wp.exe 以本地 ASPNET 帐户运行,虽然也可以使用自定义帐户。 |
Aspnet_state.exe | 可选的 Windows 服务,用于存储 ASP.NET 应用程序的会话状态。Aspnet_state.exe 可以运行在 Web 服务器或者远程机器(Web 服务器场情况下必需)上。Aspnet_state.exe 运行在本地 ASPNET 帐户下,虽然可以使用自定义帐户,通过 Services 管理单元进行配置。 |
Windows Server 2003 上的 ASP.NET 体系结构
在 Windows Server 2003 上,体系结构有所改变,因为 IIS 6 允许多个进程用于寄宿不同的 Web 应用程序。此体系结构如图 2 所示。
注 IIS 6 支持向后兼容模式,从而能够支持 IIS 5 ASP.NET 辅助进程模型。
图 2. 带有 IIS 6 的 Windows Server 2003 上的 ASP.NET 体系结构
与 Windows 2000 下的 ASP.NET 体系结构相比,Windows Server 2003 中的主要区别在于可以用不同的 IIS 辅助进程实例 (W3wp.exe) 寄宿 Web 应用程序。默认时,这些应用程序是使用 NT Authority\NetworkService 帐户运行的,这是一个最低特权本地帐户,它用作跨网络的计算机帐户。运行在网络服务帐户环境下的 Web 应用程序需要给远程服务器提供计算机的凭据以进行身份验证。
为网络服务配置 ACL
为网络服务帐户配置访问控制列表 (ACL) 的过程,对于本地和远程机器而言是不同的。如果要授予本地机器上的网络服务帐户访问权限,需要将网络服务帐户添加到 ACL 中。如果要授予远程机器上的网络服务帐户访问权限,需要将 DomainName\MachineName$ 帐户添加到 ACL 中。
注 不要把网络服务帐户与内置的网络组搞混淆了,后者包括的是跨网络进行身份验证的用户。
表 3 总结了图 2 中所描述的体系结构的主要组成部分。
表 3 Windows Server 2003 ASP.NET 体系结构的组成部分 | |
组成部分 | 说明 |
Aspnet_isapi.dll | 请求 ASP.NET 托管代码引擎处理并执行运行状况监控的队列。 |
Aspnet_filter.dll | 一个轻型的 ISAPI 筛选器,仅用于支持 ASP.NET 应用程序的无 cookie 的会话状态。Aspnet_filter.dll 运行在 W3wp.exe 内。 |
W3wp.exe | IIS 辅助进程,包含 ASP.NET 托管代码处理引擎。URL 空间可以任意在使用 IIS 6 应用程序池的不同 W3wp.exe 实例中分隔。还支持 Web 园模式。请求直接从运行在内核模式的 Http.sys 路由到 W3wp.exe 进程实例。默认时,进程运行在网络服务帐户下,但是可以配置。 |
Aspnet_state.exe | 一个可选的 Windows 服务,用于存储 ASP.NET 应用程序的会话状态。Aspnet_state.exe 可以运行在 Web 服务器或者远程机器(Web 服务器场情况下必需)上。运行在网络服务帐户下,但是可以使用 Services 管理单元配置。 |
用标识隔离应用程序
从操作系统标识的观点来看,可以通过控制用来运行每个应用程序的帐户标识隔离 ASP.NET Web应用程序。如果每个应用程序使用不同的固定帐户标识,就可以分别授权和审核每个应用程序。
注 如果要寄宿使用 .NET Framework 1.0 版构建的 ASP.NET Web应用程序,进程帐户需要适当的对当前文件系统驱动器根的访问权限。有关更多信息,请参阅 Microsoft 知识库文章 317955“”。
如果共享 Web 服务器上每个应用程序要想都使用不同的固定标识,可以采用两种方式:
• | 匿名帐户模拟 |
• | 固定标识模拟 |
匿名帐户模拟
通过匿名帐户模拟,应用程序可以模拟 IIS 指定、并为应用程序的虚拟目录配置的匿名帐户。如果您的应用程序要独立于 IIS 对用户进行身份验证(如,通过使用窗体或者 Microsoft Passport 身份验证),就可以使用此方式。在这些情况下,可以通过使用固定的匿名帐户隔离应用程序。一旦调用方通过了身份验证,角色也经过了检查,就可以将可信服务器模型用于下游的资源访问,其中已配置的匿名帐户提供了可信的标识。
为了支持这一方式,IIS 中的应用程序虚拟目录必须支持匿名访问,必须为每个应用程序配置不同的匿名帐户。应用程序然后必须配置为模拟。这种方式如图 3 所示。本地和远程资源访问假设使用模拟的匿名帐户的安全上下文。
图 3. 用于每个应用程序的多个匿名帐户
为了使用多个匿名帐户进行资源访问
此过程叙f20secmod03.gif述了如何使用多个匿名帐户(每个 Web 应用程序一个)进行资源访问,以支持单独的应用程序授权和审核。
1. | 创建新的匿名用户帐户,每个应用程序一个。 有关创建匿名用户帐户的更多信息,请参阅“”单元中的“帐户”部分。 如果需要使用匿名帐户访问远程资源,要么使用一个最低特权域帐户,要么使用本地帐户,在远程服务器上使用匹配的用户名和密码创建一个重复的本地帐户。 | ||||||||||||
2. | 使用 <location> 标记在 Machine.config 中配置每个 Web 应用程序为模拟。 <location path="Web Site Name/VDirName" allowOverride="false" > <system.web> <identity impersonate="true" /> <system.web><location> allowOverride="false" 设置防止了单个的应用程序改写 Web.config 文件中的这一设置。有关 <location> 元素的更多信息,请参阅“”单元中的“Machine.config 和 Web.config 详解”部分。 | ||||||||||||
3. | 使用 Internet 服务管理器配置每个应用程序的虚拟目录,以使用不同的匿名用户帐户。
| ||||||||||||
4. | 为每个帐户配置 NTFS 权限,以确保每个帐户都有只访问适当的文件系统文件和文件夹的权限,而不能访问关键的资源(如操作系统工具)。 有关为匿名帐户配置 NTFS 权限的更多信息,请参阅单元“”。 注 如果运行 IISLockdown 向导,它将创建一个 Web 匿名用户组。该组的成员将被拒绝访问系统目录和工具。 |
固定标识模拟
如果需要 IIS 为应用程序对用户进行身份验证(例如,通过使用集成 Windows 身份验证或者证书身份验证),可以使用一个固定模拟标识来执行 ASP.NET 应用程序。此场景如图 4 所示。
图 4. 应用程序模拟一个固定帐户,并使用它访问资源
可以配置单独的 ASP.NET 应用程序模拟一个固定帐户。这种配置的好处在于,它可以用于任何 IIS 身份验证方法,而且无需 IIS 匿名身份验证。
为了使用多个固定模拟帐户进行资源访问
此过程叙述了如何使用多个固定模拟帐户(每个 Web 应用程序一个)进行资源访问,以支持单独的应用程序授权和审核。
1. | 创建新的匿名用户帐户,每个应用程序一个。 有关创建匿名用户帐户的更多信息,请参阅“”单元中的“帐户”部分。 如果需要使用匿名帐户访问远程资源,要么使用一个最低特权域帐户,要么使用一个本地帐户,在远程服务器上使用匹配的用户名和密码创建一个重复的本地帐户。 |
2. | 在注册表中存储加密的帐户凭据。 运行 Aspnet_setreg.exe 在注册表中存储新帐户的加密凭据。有关更多信息,请参阅 Microsoft 知识库文章 329290“”。 |
3. | 配置 Web 应用程序为模拟。 可以在 Machine.config 或者 Web.config 中实现。为了配置带有不同标识的多个应用程序,可使用 Machine.config 中的 <location> 标记。按以上步骤运行 Aspnet_setreg.exe 的输出将显示 <identity> 元素的 userName 和 password 属性值所必需的格式。有些例子如下所示。 <location path="Web Site Name/appvDir1" allowOverride="false" > <system.web> <identity impersonate="true" userName= "registry:HKLM\SOFTWARE\YourApp1\identity\ASPNET_SETREG,userName" password= "registry:HKLM\SOFTWARE\YourApp1\identity\ASPNET_SETREG,password"/> </system.web></location><location path="Web Site Name/appvDir2" allowOverride="false" > <system.web> <identity impersonate="true" userName= "registry:HKLM\SOFTWARE\YourApp2\identity\ASPNET_SETREG,userName" password= "registry:HKLM\SOFTWARE\YourApp2\identity\ASPNET_SETREG,password"/> </system.web></location> 为了配置应用程序级的模拟,在应用程序的 Web.config 文件中使用一个<identity>元素,如下所示。 <identity impersonate="true" userName="registry:HKLM\SOFTWARE\YourApp\identity\ASPNET_SETREG,userName" password="registry:HKLM\SOFTWARE\YourApp\identity\ASPNET_SETREG,password |
4. | 为每个帐户配置 NTFS 权限,以确保每个帐户只有访问适当的文件系统文件和文件夹的权限,而不能访问关键的资源(如操作系统工具)。 有关为匿名帐户配置 NTFS 权限的更多信息,请参阅单元“。 |
注 在 Windows 2000 和 .NET Framework 1.0 版上,如果通过使用以上配置模拟一个固定标识,必须给用来运行 Web 应用程序的 ASP.NET 进程帐户授予“Act as part of the operating system”特权。这与最低特权的原则相反。建议您升级到 .NET Framework 1.1 版,这种要求就不再需要了。
用应用程序池隔离应用程序
如果您的应用程序运行在 Windows Server 2003 上,可以使用应用程序池,并配置每个应用程序运行在自己的辅助进程(这可以提供进程级独立)中。默认时,所有应用程序都运行在一个默认的应用程序池中。通过应用程序池,可以配置每个进程使用不同的标识运行,因此,就无需使用模拟了。
为了提供进程级独立
1. | 创建一组新的 Windows 帐户,每个应用程序一个,以运行每个辅助进程实例。 |
2. | 为每个帐户配置 NTFS 权限,以确保每个帐户只有访问只访问适当的文件系统文件和文件夹的权限,而不能访问关键的资源(如操作系统工具)。 有关为匿名帐户配置 NTFS 权限的更多信息,请参阅单元“”。 |
3. | 禁用 Web 应用程序模拟。 这可以在 Machine.config 或者 Web.config 中实现。为了在 Machine.config 中禁用多个应用程序的模拟,将 <identity> 元素放入 <location> 元素中,如下所示。 使用以下配置。此配置将不进行模拟。 <location path="Web Site Name/appvDir1" allowOverride="false" > <system.web> <identity impersonate="false" </system.web></location> 注 ASP.NET应用程序默认时不进行模拟。 |
4. | 创建新的应用程序池,并配置它们运行在新的帐户下。 使用 IIS 6 以默认设置创建新的应用程序池,使用步骤 1 中创建的帐户配置每个池的标识,这样每个池都使用不同的标识运行。 |
5. | 配置每个应用程序运行在自己的应用程序池。 在每个 IIS 应用程序的 Directory 选项卡中,为应用程序选择运行的应用程序池。 |
用代码访问安全隔离应用程序
在 .NET Framework 的 1.1 版中,可以使用 <trust> 元素配置应用程序运行在部分信任级。以下配置说明了如何从 Machine.config 配置一个应用程序的信任级。在此例中,使用了 Medium 信任级。
<location path="Web Site Name/appvDir1" allowOverride="false"> <system.web> <trust level="Medium" originUrl="" /> </system.web></location>
如果配置一个应用程序以“Full”之外的信任级运行,应用程序访问特定资源类型的代码访问安全权限将是受限制的。通过这种方式,可以约束应用程序,防止它们互相交互,以及获得访问系统级资源(如文件系统、注册表、事件日志等等的受限区域)的权限。
有关 ASP.NET 信任级、和如何使用它们提供应用程序独立以及应用程序特定的设计与开发的注意事项方面的更多信息,请参阅“”单元。
注 如果使用代码访问安全提供应用程序独立,应该还考虑到应用程序的操作系统标识。推荐的独立模型是结合使用代码访问安全和 Windows Server 2003 上的进程级独立。
窗体身份验证的问题
如果在 .NET Framework 的 1.0 版中使用窗体身份验证,应该使用不同的 cookie 路径和名称。如果不这样的话,一个应用程序中身份验证过的某个用户有可能请求另一个应用程序,而不会重定向到该应用程序的登录页。第二个应用程序中的 URL 授权规则可能连使用登录窗体提供登录凭据的机会都不给,就拒绝此用户的访问。
为了避免出现这一问题,每个应用程序的 <forms> 元素都使用唯一的 cookie 路径和名称属性,每个应用程序都使用不同的机器密钥。
.NET Framework 的 1.1 版支持如下所示的 IsolateApps 设置。
<machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey="AutoGenerate,IsolateApps" validation="SHA1"/>
这确保了机器上的每个应用程序使用不同的密钥进行窗体身份验证 cookie 和视图状态的加密以及验证。
在 .NET Framework 的 1.0 版中,不能使用 IsolateApps,而且必须手工生成 <machineKey> 元素。有关这一问题的更多信息,请参阅 Microsoft 知识库中的以下文章。
• | 313116“ ” |
• | 312906“” |
UNC 共享寄宿
如果您要运行一个内容位于通用命名约定 (UNC) 共享中的应用程序,用来访问共享的凭据要么是应用程序的凭据,要么是已通过身份验证的客户端的凭据。这是由管理员在 IIS 中配置的。
当应用程序如此配置时,ASP.NET 模拟它从 IIS 接收到的标记的安全上下文。这不能通过 <identity> 标记配置,除非提供了显式的凭据。
在 .NET Framework 的 1.0 版中,使用 Mscorcfg.msc 根据 URL 创建一个代码组,并授予它完全信任。
当使用一个指向远程共享的虚拟目录寄宿一个 ASP.NET 应用程序时,可能收到一个安全异常。有关更多信息,请参阅 Microsoft 知识库文章 320268“。”
小结
如果要在一个 Web 服务器上寄宿多个 ASP.NET 应用程序,需要考虑应用程序之间以及应用程序和共享的系统资源(如文件系统、注册表和事件日志)之间的独立。没有足够的独立性,恶意或者设计不良的应用程序可能对服务器上的其他应用程序产生负面影响。
在 Windows Server 2003 上,使用 IIS 6 支持的多辅助进程模型为应用程序提供操作系统进程独立。在 Windows 2000 上,进程独立是不可能的,虽然可以配置多个应用程序使用不同的匿名用户帐户。这提供了单独的应用程序审核,还支持独立的应用程序授权。
在两个平台上,都可以使用代码访问安全提供的资源约束模型作为附加的控制手段,以对哪些应用程序有对哪些资源类型进行访问的权限加以限制。在 ASP.NET应用程序中使用代码访问安全需要 .NET Framework 1.1 版。
有关保护 ASP.NET 应用程序安全的更多信息,请参阅“”单元。