本文提供有关 Internet Information Services (IIS) 中的标识的背景信息。
原始产品版本:
Internet 信息服务
原始 KB 编号:
4466942
应用程序池标识
若要了解应用程序池标识,必须了解什么是标识。 简单而言,标识是 Windows 帐户。 在 Windows 中运行的每个进程都在标识下运行。 应用程序由工作进程使用 Windows 标识运行。 使用的 Windows 标识依赖于应用程序池标识,该标识可以是以下任一帐户:
本地系统:
具有高特权且有权访问网络资源的受信任帐户。
网络服务:
用于运行标准、最低特权服务的受限或受限服务帐户。 此帐户的权限少于本地系统帐户。 此帐户有权访问网络资源。
本地服务:
与网络服务类似的受限或受限服务帐户,旨在运行标准、特权最低的服务。 此帐户无权访问网络资源。
ApplicationPoolIdentity:
创建新的应用程序池时,IIS 会创建一个虚拟帐户,该帐户具有新应用程序池的名称,并在此帐户下运行应用程序池辅助角色进程。 这也是一个特权最低的帐户。
自定义帐户:
除了这些内置帐户,还可以通过指定用户名和密码来使用自定义帐户。
应用程序池标识之间的差异
方案 1:事件日志访问
在此方案中,有一个 Web 应用程序 (
MyWebAppZone
) 创建自定义事件日志,并在运行时创建事件日志源
(MyWebAppZone.com
) 。 使用任何标识运行的应用程序可以使用现有事件源写入事件日志。 但是,如果他们在本地系统以外的标识下运行,则由于注册表权限不足,他们无法创建新的事件源。
例如,如果在网络服务下运行应用程序,则会收到以下安全异常:
同时运行 ProcMon 跟踪时,通常会发现 NT AUTHORITY\NETWORK SERVICE 没有以下注册表子项所需的读取和写入访问权限:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\
这是注册表中存储事件日志的所有设置的位置。
方案 2:注册表访问
除本地系统外,其他应用程序池标识没有对注册表的写入访问权限。 在此方案中,你已开发出一个简单的 Web 应用程序,可以更改和显示 Windows 自动同步的 Internet 时间服务器的名称。 如果在“本地服务”下运行此应用程序,则会出现异常。 如果检查 ProcMon 跟踪,则会发现“NT AUTHORITY\LOCAL SERVICE”应用程序池标识在以下注册表子项中没有读取和写入访问权限:
HKEY_LOCAL_MACHINE** **\SOFTWARE\Microsoft\Windows\CurrentVersion\DateTime\Servers
如果从方案 1) 检查
MyWebAppZone
事件日志 (,则会发现记录了以下错误事件。 它包含一
Requested registry access is not allowed
条错误消息。
Exception Type: SecurityException
Message: Requested registry access is not allowed.
Stack Trace
at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
at Identities.ChangeTimeServer.Page_Load(Object sender, EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest()
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at ASP.changetimeserver_aspx.ProcessRequest(HttpContext context) in c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\fd06117a\f8c94323\App_Web_ysqbhk00.2.cs:line 0
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
方案 3:Kerberos 身份验证和负载均衡环境中的自定义帐户
你已在方案 1 和 2 中看到了内置帐户之间的一些差异。 现在,我们来讨论什么是自定义帐户,以及在负载均衡环境中使用 Kerberos 身份验证时,它与内置帐户的优点。
通过使用此方法,可以在配置为使用特定 Windows 标识运行的应用程序池中运行应用程序。 请考虑下图,其中应用程序托管在负载均衡环境中,其中包含两台服务器,并使用 Kerberos 身份验证来标识客户端。
若要运行 Kerberos 身份验证,必须使用两个服务器的计算机帐户为这两台服务器设置 SPN。 如果应用程序池在内置帐户下运行,它将在网络上显示计算机凭据。 例如,如果计算机名称为 Server1,则会显示为“Server1$”。 当计算机加入域时,会自动创建此计算机帐户。 因此,如果有 N 服务器,则必须设置与其各自的计算机帐户相对应的 N 个 SPN 数。
将 SPN 注册到计算机帐户:
setspn -a HTTP/HOSTNAME MachineAccount$
setspn -a HTTP/MyWebAppZone.com Server1$
若要克服此缺点,可以在自定义 Windows (域) 标识下运行应用程序,然后将 SPN 设置为域控制器中的特定域帐户。
将 SPN 注册到域帐户:
setspn -a HTTP/HOSTNAME domain\account
setspn -a HTTP/MyWebAppZone.com contoso.com\account_alias
wwwroot 中的默认权限和用户权限
IIS 7.0 及更高版本还可以更轻松地配置应用程序池标识并进行所有必要的更改。 当 IIS 启动辅助角色进程时,它必须创建进程将使用的令牌。 创建此令牌后,IIS 会在运行时自动将成员身份添加 IIS_IUSRS
到辅助角色进程令牌。 作为 应用程序池标识 运行的帐户不再必须是组的 IIS_IUSRS
显式部分。 如果创建网站,然后将物理位置指向 C:\inetpub\wwwroot
以下用户和组,则会自动添加到网站的访问控制列表中。
允许的权限
如果要禁用此功能并将帐户手动添加到IIS_IUSRS
组,请在ApplicationHost.config文件中将 manualGroupMembership 值设置为 true。 以下示例演示如何对默认应用程序池执行此操作:
<applicationPools>
<add name="DefaultAppPool">
<processModel manualGroupMembership="true" />
</applicationPools>
了解配置隔离
IIS 辅助角色进程对 ApplicationHost.config 文件没有读取访问权限。 因此,你可能想知道他们如何读取此文件中的任何配置集。
答案是使用 IIS 7.0 及更高版本中的配置隔离功能。 Windows Process Activation Service ( WAS) 生成此文件的筛选副本,而不是让 IIS 辅助角色进程在读取配置文件层次结构时直接读取ApplicationHost.config。 在 IIS 辅助角色进程中读取配置时,每个 IIS 工作进程都使用这些副本替换 ApplicationHost.config 。 这些文件默认在目录中 %SystemDrive%\inetpub\Temp\appPools
生成,名为 {AppPoolName}.config。这些文件配置为使用 IIS APPPOOL\AppPoolName
应用程序池安全标识符 (SID) ,仅允许访问相应应用程序池中的 IIS 辅助角色进程。
若要了解有关 SID 的详细信息,请参阅 安全标识符。
这样做是为了防止应用程序池 A 中的 IIS 辅助角色进程读取用于应用程序池 B 的ApplicationHost.config 文件中的配置信息。
ApplicationHost.config 可能包含敏感的个人信息,例如自定义应用程序池标识的用户名和密码,或虚拟目录的用户名和密码。 因此,允许所有应用程序池访问 ApplicationHost.config 将中断应用程序池隔离。 如果向每个应用程序池授予对 ApplicationHost.config 文件的直接访问权限,则这些池可以运行以下命令,轻松地从其他应用程序池中破解敏感信息:
appcmd list APPPOOL "DefaultAppPool" /text:*
IUSR - 匿名身份验证
匿名身份验证允许用户访问网站的公共区域,而不会提示用户名或密码。 在 IIS 7.0 及更高版本中,内置帐户 IUSR
用于提供匿名访问。 此内置帐户不需要密码。 它将是启用匿名身份验证时使用的默认标识。 在 ApplicationHost.config 文件中,可以看到以下定义:
<authentication>
<anonymousAuthentication enabled="true" userName="IUSR" />
</authentication>
这会告知 IIS 对所有匿名身份验证请求使用新的内置帐户。 执行此操作的最大优点是:
你不再需要担心此帐户的密码即将过期。
可以使用 xcopy /o 将文件及其所有权和 ACL 信息无缝复制到不同的计算机。
还可以使用特定的 Windows 帐户或应用程序池标识(而不是 IUSR
帐户)向网站提供匿名身份验证。
IUSR 与 Connect 作为
作为 IIS 中的一个选项进行连接,可让你确定要用于访问网站的凭据。 可以使用经过身份验证的用户凭据或特定的用户凭据。 若要了解差异,请考虑以下方案:
你有一个默认网站,配置为使用匿名身份验证。 但是,您的网站内容位于另一台服务器上,并且使用 “连接”作为 部分通过 Test
域用户访问该资源。 当用户登录时,他使用 IUSR 帐户进行身份验证。 但是,网站内容是通过 “连接为 ”部分中提到的用户凭据访问的。
更简单地说,匿名身份验证是网站用来标识用户的机制。 但是,使用此功能时,用户无需提供任何凭据。 但是,可能存在类似的情况:内容位于网络共享上。 在这种情况下,不能使用内置帐户来访问网络共享。 相反,必须使用特定帐户 (域) 来执行此操作。
ASP.NET 模拟
从字面上讲,模拟意味着假装是另一个人的行为。 在技术方面,它是一项 ASP.NET 安全功能,它提供控制运行应用程序代码的标识的能力。 当 ASP.NET 在经过身份验证的客户端和授权客户端的上下文中运行代码时,会发生模拟。 IIS 使用帐户提供对资源的 IUSR
匿名访问。 将请求传递到 ASP.NET 后,将使用应用程序池标识运行应用程序代码。
如果应用程序使用匿名身份验证,并且以下条件之一为 true,则可以通过 IIS 和 ASP.NET 代码启用模拟:
如果 IMPERSONATION
禁用,则应用程序池标识用于运行应用程序代码。
如果 IMPERSONATION
已启用, NT AUTHORITY\IUSR
则用于运行应用程序代码。
通过 IIS 启用后 impersonation
,它会在应用程序的Web.config文件中添加以下标记,以模拟 IIS 身份验证帐户或用户: <identity impersonate=“true” />
若要为 ASP.NET 应用程序的所有页面上的所有请求模拟特定用户,可以在该应用程序的Web.config文件的标记中 <identity>
指定用户名和密码属性。
<identity impersonate="true" userName="accountname" password="password" />
若要通过 ASP.NET 代码实现模拟,请参阅 ASP.NET 应用程序中实现模拟
打开模拟 Test
本地用户的测试网站的 IIS 工作进程,并检查是否可以找到运行应用程序代码的模拟帐户。
应用程序的应用程序池标识设置为 ApplicationPoolIdentity,使用帐户提供 IUSR
匿名身份验证。 可以使用 ProcMon 轻松跟踪模拟标识。 例如,如果检查与要检查的w3wp.exe过程相对应的 CreateFile 事件之一,则可以找到模拟帐户,如以下屏幕截图所示。