了解 IIS 中的标识

本文提供有关 Internet Information Services (IIS) 中的标识的背景信息。

原始产品版本: Internet 信息服务
原始 KB 编号: 4466942

应用程序池标识

若要了解应用程序池标识,必须了解标识是什么。 简单来说,标识就是 Windows 帐户。 Windows 中运行的每个进程都在标识下运行。 应用程序由工作进程使用 Windows 标识运行。 使用的 Windows 标识依赖于应用程序池标识,它可以是以下任何帐户:

Windows 标识帐户。

  • 本地系统: 具有高特权且有权访问网络资源的受信任帐户。
  • 网络服务: 用于运行标准最低特权服务的受限或受限服务帐户。 此帐户的特权比本地系统帐户少。 此帐户有权访问网络资源。
  • 本地服务: 受限或受限服务帐户,类似于网络服务,旨在运行标准的最低特权服务。 此帐户无权访问网络资源。
  • ApplicationPoolIdentity: 创建新的应用程序池时,IIS 会创建一个虚拟帐户,该帐户具有新应用程序池的名称,并在此帐户下运行应用程序池工作进程。 这也是最低特权帐户。
  • 自定义帐户: 除了这些内置帐户,还可以通过指定用户名和密码来使用自定义帐户。

应用程序池标识之间的差异

  • 方案 1:事件日志访问

    在此方案中,你有一个 Web 应用程序 (MyWebAppZone) 创建自定义事件日志,并在运行时 (MyWebAppZone.com) 事件日志源。 使用任何标识运行的应用程序可以使用现有事件源写入事件日志。 但是,如果它们以本地系统以外的标识运行,则由于注册表权限不足,它们无法创建新的事件源。

    我的 Web 应用区域。

    例如,如果在“网络服务”下运行应用程序,则会收到以下安全异常:

    服务器错误的屏幕截图。

    同时运行 ProcMon 跟踪时,通常会发现 NT AUTHORITY\NETWORK SERVICE 对以下注册表子项没有所需的读取和写入访问权限:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\

    这是注册表中存储事件日志的所有设置的位置。

    进程监视器 1 的屏幕截图。

  • 方案 2:注册表访问

    除本地系统外,其他任何应用程序池标识都没有对注册表的写入访问权限。 在此方案中,你开发了一个简单的 Web 应用程序,该应用程序可以更改和显示 Windows 自动同步的 Internet 时间服务器的名称。 如果在“本地服务”下运行此应用程序,则会出现异常。 如果检查 ProcMon 跟踪,你会发现“NT AUTHORITY\LOCAL SERVICE”应用程序池标识在以下注册表子项中没有读取和写入访问权限:

    HKEY_LOCAL_MACHINE** **\SOFTWARE\Microsoft\Windows\CurrentVersion\DateTime\Servers

    进程监视器 2 的屏幕截图。

    如果从方案 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 身份验证的屏幕截图。

    若要使 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_USRS 读取和执行
TrustedInstaller 完全控制

如果要禁用此功能并手动将帐户添加到IIS_IUSRS组,请在 ApplicationHost.config 文件中将 manualGroupMembership 值设置为 true。 以下示例演示如何对默认应用程序池执行此操作:

<applicationPools> 
    <add name="DefaultAppPool"> 
        <processModel manualGroupMembership="true" />
    </add>
</applicationPools>

了解配置隔离

IIS 工作进程对 ApplicationHost.config 文件没有读取访问权限。 因此,你可能想知道他们如何读取此文件中的任何配置集。

答案是使用 IIS 7.0 及更高版本中的配置隔离功能。 Windows 进程激活服务 (WAS) 生成此文件的筛选副本,而不是让 IIS 工作进程在读取配置文件层次结构时直接读取ApplicationHost.config。 在 IIS 工作进程中读取配置时,每个 IIS 工作进程使用这些副本来替换 ApplicationHost.config 。 默认情况下,这些文件在 %SystemDrive%\inetpub\Temp\appPools 目录中生成,名为 {AppPoolName}.config。这些文件配置为仅允许访问相应应用程序池中的 IIS 工作进程,方法是使用 IIS APPPOOL\AppPoolName 应用程序池安全标识符 (SID) 。

注意

若要详细了解 SID,请参阅 安全标识符

使用应用程序池进行配置隔离的屏幕截图。

这样做是为了防止应用程序池 A 中的 IIS 工作进程能够读取适用于应用程序池 B 的ApplicationHost.config 文件中的配置信息。

ApplicationHost.config 可能包含敏感个人信息,例如自定义应用程序池标识的用户名和密码,或虚拟目录的用户名和密码。 因此,允许所有应用程序池访问 ApplicationHost.config 将中断应用程序池隔离。 如果向每个应用程序池授予对 ApplicationHost.config 文件的直接访问权限,则这些池可以通过运行以下命令轻松地从其他应用程序池中破解敏感信息:

appcmd list APPPOOL "DefaultAppPool" /text:*

使用 appcmd 命令的屏幕截图。

IUSR - 匿名身份验证

匿名身份验证允许用户访问网站的公共区域,而无需系统提示输入用户名或密码。 在 IIS 7.0 及更高版本中,内置帐户 IUSR用于提供匿名访问。 此内置帐户不需要密码。 这将是启用匿名身份验证时使用的默认标识。 在 ApplicationHost.config 文件中,可以看到以下定义:

<authentication>
     <anonymousAuthentication enabled="true" userName="IUSR" />
 </authentication>

这会告知 IIS 对所有匿名身份验证请求使用新的内置帐户。 执行此操作的最大优势如下:

  • 你不再需要担心此帐户的密码过期。
  • 可以使用 xcopy /o 将文件及其所有权和 ACL 信息无缝复制到不同的计算机。

还可以使用特定的 Windows 帐户或应用程序池标识(而不是 IUSR 帐户)向网站提供匿名身份验证。

IUSR 与 Connect as

作为 IIS 中的一个选项进行连接,使你能够决定要使用哪些凭据来访问网站。 可以使用经过身份验证的用户凭据或特定用户凭据。 若要了解差异,请考虑以下方案:

你有一个配置为使用匿名身份验证的默认网站。 但是,你的网站内容位于另一台服务器上,并且你正在使用 “连接为 ”部分通过 Test 域用户访问该资源。 当用户登录时,将使用 IUSR 帐户对他进行身份验证。 但是,网站内容是通过 “连接为 ”部分中提到的用户凭据访问的。

简单地说,匿名身份验证是网站用来标识用户的机制。 但是,使用此功能时,用户无需提供任何凭据。 但是,可能存在类似的情况,即内容位于网络共享上。 在这种情况下,不能使用内置帐户访问网络共享。 相反,必须使用特定帐户 (域) 执行此操作。

ASP.NET 模拟

从字面上讲,模拟是指假装是另一个人的行为。 在技术方面,它是一种 ASP.NET 安全功能,可提供控制运行应用程序代码的标识的能力。 当 ASP.NET 在经过身份验证和授权的客户端的上下文中运行代码时,将发生模拟。 IIS 使用 IUSR 帐户提供对资源的匿名访问。 将请求传递到 ASP.NET 后,将使用应用程序池标识运行应用程序代码。

如果应用程序使用匿名身份验证,并且满足以下条件之一,则可以通过 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 事件之一,则可以找到模拟帐户,如以下屏幕截图所示。

事件属性中模拟的详细信息。