应用程序池标识和 SQL Server Express

作者:Thomas Deml

介绍

Windows 7 或 Windows Server 2008 R2 上的 IIS 7.5 支持名为“应用程序池标识”的新功能。 它能够有效隔离应用程序池,而无需为每个应进行沙盒化的应用程序池维护用户帐户。 应用程序池标识是自动生成的,不需要密码,这使得管理成本降低。

与每个新功能一样,应用程序池标识功能也有一些缺点。 本文介绍将 IIS 7.5 与 SQL Express 一起使用时 Web 应用程序开发人员可能遇到的问题。

拼图碎片

SQL Express 支持名为“用户实例”或 RANU(作为普通用户运行)的功能。如果启用此功能(打开它与将“UserInstance=true”添加到连接字符串一样简单),则在用户打开数据库连接时启动的 SQL Server 进程将在与连接用户相同的帐户下运行。 从安全的角度来看,RANU 非常理想。

使用 Visual Studio 2008 或 Visual Studio 2010 进行开发时,默认连接字符串存储在 machine.config 文件中。 如下所示:

<connectionStrings>
  <add name="LocalSqlServer" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>
...

默认连接字符串使用 RANU (Instance=true),如你所见。 例如,当功能要求数据库存储某些数据但尚未配置数据库时,将使用默认连接字符串。 ASP.NET 成员身份是一个很好的例子。 如果开发人员将成员身份功能添加到 Web 应用程序,ASP.NET 将自动使用 machine.config 中的默认连接字符串创建数据库和必要的表。

问题

现在的问题是:

现成的 RANU 不适用于新的“应用程序池标识”功能。 “应用程序池标识”功能是 IIS 7.5 中的默认标识。 例如,IIS 7.5 DefaultAppPool 在 IIS AppPool\DefaultAppPool 标识下运行,不再作为 NetworkService 运行。 出于此原因,如果你也使用 Visual Studio 进行开发,则可能会遇到此问题。

下面是你可能会看到的错误页:

Screenshot shows server error in S Q L test application.

此错误的出现是由于 SQL Server Express RANU 要求加载用户配置文件,而 IIS 7.5 默认不加载用户配置文件。 在早期版本的 IIS 中看不到此错误,因为 DefaultAppPool 是作为 NetworkService 运行的,且操作系统会预加载 NetworkService 的用户配置文件。

修复方法

幸运的是,此问题的修复非常简单。 IIS 让你只需将应用程序池上的 LoadUserProfile 设置设为 true 即可加载应用程序池的用户配置文件。

这可以通过用户界面完成:

  1. 单击 IIS 管理器中的“应用程序池”节点。
  2. 选择相关的应用程序池,例如 DefaultAppPool
  3. 单击右侧“操作”菜单中的“高级设置...”。
  4. 在“进程模型”子部分中,可以找到名为“加载用户配置文件”的行。 请切换到“true”

如果要通过命令行执行此操作,请在提升的命令提示符中执行以下命令:

%windir%\system32\inetsrv\appcmd set config -section:applicationPools /[name='DefaultAppPool'].processModel.loadUserProfile:false

加载用户配置文件的副作用

加载用户配置文件的最大副作用可能是临时目录。 如果未加载用户配置文件,则 %temp% 环境变量会指向 \windows\temp 目录。 每个人都可以写入此目录。 如果加载了用户配置文件,则 %temp% 环境变量会指向仅用户有权访问的专用目录。 因此,如果 DefaultAppPool 作为“IIS AppPool\DefaultAppPool”运行,则 %temp% 变量会指向 C:\Users\DefaultAppPool\AppData\Local\Temp 目录。 只有 DefaultAppPool 和管理员对此目录具有写入访问权限。

那么,为什么这是个问题呢? 遗憾的是,Windows 操作系统支持一项名为“模拟”的功能。 模拟功能允许一段代码在与进程运行身份不同的标识下运行。 某些 Web 应用程序框架利用了此功能。 例如,经典 ASP 能将所有代码作为模拟执行。 使用的标识是 IIS 配置存储中配置的匿名用户,或者通过 IIS 提供的身份验证方案(Basic、Digest 或 Windows)进行身份验证的用户。 ASP.NET 不会模拟它默认运行的代码。 在配置中使用 system.web 标识部分或使用 .NET API 时仍支持模拟。 问题是模拟标识可能无权访问 %temp% 目录。 下面是一篇解释此问题的一个实例的文章

如果你只开发 ASP.NET 应用程序,并且不使用标识部分,那么你可能永远不会看到这些问题,并且加载用户配置文件应该是完全安全的。

总结

本文介绍了 SQL Express 和新 IIS 7.5 应用程序池标识的问题。 由于应用程序池标识功能是 IIS 7.5 中的默认设置,因此用户在开发环境中使用 SQL Express 时(即使用 Visual Studio 进行开发时)可能会看到上述问题。 此问题不会在生产环境中发生,因为生产环境不支持 SQL Express。