排查 Internet Explorer 中的 Kerberos 故障

本文可帮助你在访问配置为在 Internet Explorer 中使用 Kerberos 身份验证的网站时隔离并修复各种错误的原因。 潜在问题的数量几乎与可用于解决这些问题的工具数量相同。

Kerberos 失败时的常见症状

你尝试访问已配置 Windows 集成身份验证的网站,并且你希望使用 Kerberos 身份验证协议。 在这种情况下,浏览器会立即提示你输入凭据,如下所示:

提示输入凭据的屏幕截图。

虽然输入了有效的用户名和密码,但系统会再次提示你 (总共) 三个提示。 然后,将显示一个屏幕,指示你不允许访问所需的资源。 屏幕显示类似于以下错误的 HTTP 401 状态代码:

未授权
HTTP 错误 401。 请求的资源需要用户身份验证。

H T T P 错误 401 的屏幕截图。

在 Microsoft Internet Information Services (IIS) 服务器上,网站日志包含以 401.2 状态代码结尾的请求,例如以下日志:

#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken  
DateTime IP GET /whoami.aspx - 80 – IP Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+10.0;+WOW64;+Trident/7.0;+.NET4.0C;+.NET4.0E;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.30729;+.NET+CLR+3.5.30729) - 401 2 5 1270  
DateTime IP GET /whoami.aspx - 80 - IP Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+10.0;+WOW64;+Trident/7.0;+.NET4.0C;+.NET4.0E;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.30729;+.NET+CLR+3.5.30729) - 401 2 5 8

或者,屏幕显示 401.1 状态代码,例如以下日志:

#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken  
DateTime IP GET /whoami.aspx - 80 - IP Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+10.0;+WOW64;+Trident/7.0;+.NET4.0C;+.NET4.0E;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.30729;+.NET+CLR+3.5.30729) - 401 2 5 105  
DateTime IP GET /whoami.aspx - 80 - IP Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+10.0;+WOW64;+Trident/7.0;+.NET4.0C;+.NET4.0E;+.NET+CLR+2.0.50727;+.NET+CLR+3.0.30729;+.NET+CLR+3.5.30729) - 401 1 2148074245 18

确定是否使用 Kerberos

排查 Kerberos 身份验证失败问题时,建议尽量减少配置。 即,一个客户端、一个服务器和一个在默认端口上运行的 IIS 站点。 此外,还可以按照一些基本的故障排除步骤进行操作。 例如,使用测试页验证使用的身份验证方法。 如果使用 ASP.NET,则可以创建此 ASP.NET 身份验证测试页

如果使用经典 ASP,可以使用以下Testkerb.asp页:

<%
    authType=UCase(Request.ServerVariables("AUTH_TYPE"))
    authHeader=Request.ServerVariables("HTTP_AUTHORIZATION")
    response.write " Authentication Method : " & authType & "<BR>"
    LenAuthHeader = len(authHeader)
    response.write " Protocol : "
    if Len(authType ) =0 then response.write " Anonymous" else if authType<>"NEGOTIATE" then response.write authType else if LenAuthHeader>1000 then response.write "Kerberos" else response.write  "NTLM"
%>

还可以使用以下工具确定是否使用 Kerberos:

  • Fiddler
  • HttpWatch
  • 网络监视器
  • 浏览器中的开发人员工具

有关如何生成此类跟踪的详细信息,请参阅 客户端跟踪

使用 Kerberos 时,客户端发送的请求 (大于 2,000 字节) ,因为 HTTP_AUTHORIZATION 标头包含 Kerberos 票证。 以下请求适用于使用基于 Kerberos 的 Windows 身份验证对传入用户进行身份验证的页面。 GET 请求的大小超过 4,000 个字节。

超过 4,000 字节的请求的屏幕截图。

如果使用 NTLM 握手,请求将小得多。 以下客户端捕获显示了 NTLM 身份验证请求。 GET 请求小得多, (小于 1,400 字节) 。

小于 1,400 字节的请求的屏幕截图。

确定 Kerberos 身份验证失败后,按给定顺序检查以下各项。

Kerberos 身份验证失败时要检查的内容

以下部分介绍了在 Kerberos 身份验证失败时可用于检查的内容。

客户端和服务器是否位于同一域中

使用 Kerberos 需要域,因为 Kerberos 票证由域控制器 (DC) 传递。 在以下情况下,还可能采用高级方案:

  • 客户端和服务器不在同一域中,而是位于同一林的两个域中。
  • 客户端和服务器位于两个不同的林中。

本文的 Kerberos 委派为何在我的两个林之间失败(尽管它曾经工作 过)一节中讨论了这些可能的方案。

IIS 是否配置为使用集成身份验证

Windows 身份验证设置的屏幕截图。

Internet Explorer 中是否启用了集成身份验证

在“Internet 选项”页中选择“启用集成 Windows 身份验证”选项。

使用的 URL 是否解析为可以为其发送凭据的安全区域

始终为以下网站运行此检查:

  • 与浏览器的本地 Intranet 区域匹配的站点。
  • “受信任的站点”区域中的站点。

可以检查浏览器决定在哪个区域包含站点。 为此,请打开 Internet Explorer 的“ 文件 ”菜单,然后选择“ 属性”。 “ 属性” 窗口将显示浏览器决定包含要浏览到的站点的区域。

检查 Internet Explorer 的“属性”中的区域。

可以检查包含站点的区域是否允许自动登录。 为此,请打开 Internet Explorer 的 “Internet 选项 ”菜单,然后选择“ 安全 ”选项卡。选择所需区域后,选择“ 自定义级别 ”按钮以显示设置,并确保已选择 “自动登录 ”。 (通常,默认情况下,Intranet 和受信任的站点区域) 启用此功能。

检查是否选择了“自动登录”。

注意

即使通过此配置并不常见, (因为它要求客户端有权访问 DC) ,Kerberos 可用于 Internet 区域中的 URL。 在这种情况下,除非更改了默认设置,否则浏览器将始终提示用户输入凭据。 Kerberos 委派在 Internet 区域中不起作用。 这是因为 Internet Explorer 仅允许对 Intranet 和受信任站点区域中的 URL 进行 Kerberos 委派。

IIS 服务器是否配置为发送 WWW-Authenticate: Negotiate 标头

检查 IIS 服务器是否配置为发送 WWW-Authenticate: Negotiate 标头。

如果 IIS 不发送此标头,请使用 IIS 管理器控制台通过 NTAuthenticationProviders 配置属性设置 Negotiate 标头。 有关详细信息,请参阅 Windows 身份验证提供程序 <提供程序>。 可以通过 IIS 管理器中 Windows 身份验证详细信息的 “提供程序” 设置来访问控制台。

身份验证中的提供程序设置。

注意

默认情况下,未设置 NTAuthenticationProviders 属性。 这会导致 IIS (NTLM) 标头发送 Negotiate 和 Windows NT LAN Manager。

客户端和服务器是否安装在同一台计算机上

默认情况下,此配置中未启用 Kerberos。 若要更改此行为,必须设置 DisableLoopBackCheck 注册表项。 有关详细信息,请参阅 知识库926642

客户端能否获取 Kerberos 票证

可以使用 Kerberos 列表 (KLIST) 工具验证客户端计算机是否可以获取给定服务主体名称的 Kerberos 票证。 在此示例中,SPN) (服务主体名称为 http/web-server。

注意

KLIST 是自 Windows Server 2008 以来的本机 Windows 工具,适用于服务器端操作系统,Windows 7 Service Pack 1 适用于客户端操作系统。

使用 KLIST 工具验证客户端计算机是否可以获取给定服务主体名称的 Kerberos 票证。

当 Kerberos 票证请求失败时,不使用 Kerberos 身份验证。 可能会发生 NTLM 回退,因为请求的 SPN 对 DC 未知。 如果 DC 无法访问,则不会发生 NTLM 回退。

若要声明 SPN,请参阅以下文章:

配置 Internet Information Services 上托管的 Web 应用程序时如何使用 SPN

Web 服务器是否使用默认 (80)

默认情况下,Internet Explorer 不会在 SPN 中包含用于请求 Kerberos 票证的端口号信息。 如果使用 IIS 在不同的端口和标识下托管多个站点,则可能是一个问题。 在此配置中,Kerberos 身份验证可能仅适用于特定站点,即使已在 Active Directory 中正确声明了所有 SPN 也是如此。 若要解决此问题,必须设置 FEATURE_INCLUDE_PORT_IN_SPN_KB908209 注册表值。 (有关如何声明密钥的信息,请参阅 Internet Explorer 功能密钥 部分。) 此设置强制 Internet Explorer 在用于请求 Kerberos 票证的 SPN 中包含端口号。

Internet Explorer 是否使用预期的 SPN

如果使用别名 (CNAME) 访问网站,Internet Explorer 首先使用 DNS 解析将别名解析为计算机名称 (ANAME) 。 然后,计算机名称用于生成 SPN 并请求 Kerberos 票证。 即使 Internet Explorer 地址栏中输入的 URL 为 http://MYWEBSITE,如果 MYWEBSITE 是 MYSERVER (ANAME) 的别名 (CNAME) ,Internet Explorer 也会请求 HTTP/MYSERVER 的 SPN。 可以使用注册表项更改此行为 FEATURE_USE_CNAME_FOR_SPN_KB911149 。 (有关如何声明密钥的信息,请参阅 Internet Explorer 功能键 。)

网络监视器跟踪是检查与 Kerberos 票证关联的 SPN 的好方法,如以下示例所示:

- Http: Request, GET /whoami.aspx , Using GSS-API Authorization
    Command: GET
  - URI: /whoami.aspx
     Location: /whoami.aspx
    ProtocolVersion: HTTP/1.1
    Accept:  image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*
    Accept-Language:  en-US,en;q=0.5
    UserAgent:  Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
    Accept-Encoding:  gzip, deflate
    Host:  web-server
    Connection:  Keep-Alive
  - Authorization: Negotiate
   - Authorization:  Negotiate YIILcAYGKwYBBQUCoIILZDCCC2CgMDAuBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICHgYKKwYBBAGCNwICCqKCCyoEggsmYIILIgYJKoZIhvcSAQICAQBuggsRMIILDaADAgEFoQMCAQ6iBwMFACAAAACjggRtYYIEaTCCBGWgAwIBBaEOGwxPREVTU1kuTE9DQUyiKjAooAMCAQKhITAfGwRIVFRQG
      WhiteSpace:  
    - NegotiateAuthorization:
       Scheme: Negotiate
     - GssAPI: 0x1
      - InitialContextToken:
       + ApplicationHeader:
       + ThisMech: SpnegoToken (1.3.6.1.5.5.2)
       - InnerContextToken: 0x1
        - SpnegoToken: 0x1
         + ChoiceTag:
         - NegTokenInit:
          + SequenceHeader:
          + Tag0:
          + MechTypes: Prefer MsKerberosToken (1.2.840.48018.1.2.2)
          + Tag2:
          + OctetStringHeader:
          - MechToken: 0x1
           - MsKerberosToken: 0x1
            - KerberosInitToken:
             + ApplicationHeader:
             + ThisMech: KerberosToken (1.2.840.113554.1.2.2)
             - InnerContextToken: 0x1
              - KerberosToken: 0x1
                 TokId: Krb5ApReq (0x100)
               - ApReq: KRB_AP_REQ (14)
                + ApplicationTag:
                + SequenceHeader:
                + Tag0:
                + PvNo: 5
                + Tag1:
                + MsgType: KRB_AP_REQ (14)
                + Tag2: 0x1
                + ApOptions:
                + Tag3:
                - Ticket: Realm: ODESSY.LOCAL, Sname: HTTP/web-server.odessy.local
                 + ApplicationTag:
                 + SequenceHeader:
                 + Tag0:
                 + TktVno: 5
                 + Tag1:
                 + Realm: ODESSY.LOCAL
                 + Tag2: 0x1
                 + Sname: HTTP/web-server.odessy.local
                 + Tag3: 0x1
                 + EncPart:
                + Tag4:

应用程序池标识是否与 SPN 关联的帐户匹配

当 Kerberos 票证从 Internet Explorer 发送到 IIS 服务器时,票证将使用私钥进行加密。 私钥是用于与 SPN 关联的用户帐户的密码哈希。 因此,只有在此帐户下运行的应用程序才能解码票证。

以下过程是 Kerberos 身份验证算法的摘要:

  1. Internet Explorer 使用在地址栏中输入的 URL 确定 SPN。

  2. SPN 通过安全支持提供程序接口 (SSPI) API (InitializeSecurityContext) 传递到负责 Windows 安全 (本地安全机构子系统服务 (LSASS) 进程) 的系统组件。 在此阶段,可以看到 Internet Explorer 代码未实现任何代码来构造 Kerberos 票证。 Internet Explorer 仅调用 SSPI API。

  3. LSASS 使用传入的 SPN 向 DC 请求 Kerberos 票证。 如果 DC 可以 (已知的 SPN) 处理请求,则会创建 Kerberos 票证。 然后,它通过使用从与 SPN 关联的帐户的用户帐户密码哈希构造的密钥来加密票证。 然后,LSASS 会将票证发送到客户端。 就 Internet Explorer 而言,票证是不透明的 blob。

  4. Internet Explorer 将 LSASS 提供的 Kerberos 票证封装在标头中 Authorization: Negotiate ,然后将票证发送到 IIS 服务器。

  5. IIS 处理请求,并使用指定的主机标头将其路由到正确的应用程序池。

  6. 应用程序池尝试使用 SSPI/LSASS API 并遵循以下条件来解密票证:

    • 如果票证可以解密,则 Kerberos 身份验证会成功。 与票证关联的所有服务 (模拟、委派(如果票证允许)等) 可用。

    • 如果票证无法解密,则会返回 Kerberos 错误 (KRB_AP_ERR_MODIFIED) 。 此错误是一个通用错误,指示票证在运输过程中以某种方式更改。 因此无法解密票证。 此错误也会记录在 Windows 事件日志中。

如果未显式声明 SPN,则 Kerberos 身份验证仅适用于以下应用程序池标识之一:

  • 网络服务
  • ApplicationPoolIdentity
  • 另一个系统帐户,例如 LOCALSYSTEM 或 LOCALSERVICE

但不建议使用这些标识,因为它们存在安全风险。 在这种情况下,Kerberos 票证是使用在 Active Directory 中创建的默认 SPN 生成的,在这种情况下,当计算机 (时,IIS 在) 上运行的服务器将添加到域。 此默认 SPN 与计算机帐户相关联。 在 IIS 下,计算机帐户映射到网络服务或 ApplicationPoolIdentity。

如果应用程序池必须使用列出的标识以外的标识,请使用 SETSPN) 声明 SPN (。 然后将它与用于应用程序池标识的帐户相关联。 一个常见错误是创建具有不同帐户的类似 SPN。 例如:

  • SETSPN http/mywebsite UserAppPool1
  • SETSPN http/mywebsite UserAppPool2

此配置将不起作用,因为没有确定性方法可以知道是否使用 UserAppPool1 或 UserAppPool2 密码加密 http/mywebsite SPN 的 Kerberos 票证。 此配置通常会生成KRB_AP_ERR_MODIFIED错误。 若要确定你是否处于这种错误的重复 SPN 方案中,请使用以下文章中所述的工具:

为什么在 AD 2012 R2 和 AD 2016 中仍可以有重复的 SPN

从 Windows Server 2008 开始,还可以使用 Windows 的更新版本的 SETSPN,以便在为目标帐户声明新的 SPN 时使用 setspn –X 命令检测重复的 SPN。 有关详细信息,请参阅 Setspn

我们还建议查看以下文章:

即使 Kerberos 身份验证在 IIS 6 中工作,在 IIS 7 及更高版本中是否失败

内核模式身份验证是在 IIS 7 中引入的一项功能。 它具有以下优点:

  • 性能会提高,因为不再进行内核模式到用户模式的转换。
  • Kerberos 票证解码是使用计算机帐户而不是应用程序池标识进行的。 通过此更改,可以在不同标识下运行多个应用程序池,而无需声明 SPN。

警告

如果已为特定用户帐户声明 SPN (也用作应用程序池标识) ,内核模式身份验证无法解密 Kerberos 票证,因为它使用计算机帐户。 此问题在 Web 场方案中很常见。 此方案通常为 (虚拟) NLB 主机名声明 SPN。 若要防止此问题,请使用以下方法之一:

  • 禁用内核模式身份验证。 从性能角度来看,不建议 (。)
  • useAppPoolCredentials 设置为 true。 这样做可以保留内核模式身份验证的性能优势,同时允许在应用程序池标识下解码 Kerberos 票证。 有关详细信息,请参阅 安全身份验证 <身份验证>

为什么委派失败,尽管 Kerberos 身份验证有效

在此方案中,检查以下项:

  • 用于 URL 的 Internet Explorer 区域。 仅对 Intranet 和受信任的站点区域允许 Kerberos 委派。 (换句话说,仅当确定的区域是 Intranet 或受信任的站点时,Internet Explorer 才会在调用 InitializeSecurityContext 时设置ISC_REQ_DELEGATE标志。)

  • 托管站点的 IIS 应用程序池的用户帐户必须在 Active Directory 中设置 “受信任的委派 ”标志。

如果委派仍然失败,请考虑使用适用于 IIS 的 Kerberos Configuration Manager。 借助此工具,可以诊断和修复用于 Kerberos 身份验证和目标帐户上关联 SPN 的 IIS 配置。 有关详细信息,请参阅 README.md。 可以从 此处下载该工具。

为什么使用 Kerberos 身份验证时性能不佳

Kerberos 是旧版 Windows Server 中基于请求的身份验证协议,例如 Windows Server 2008 SP2 和 Windows Server 2008 R2。 这意味着客户端必须发送 Kerberos 票证 (,该票证可能是一个相当大的 blob) 向服务器发出的每个请求。 这与依赖于 NTLM 的身份验证方法相反。 默认情况下,NTLM 是基于会话的。 这意味着浏览器在打开与服务器的 TCP 连接时,只会对一个请求进行身份验证。 同一 TCP 连接上的每个后续请求不再需要身份验证才能接受请求。 在较新版本的 IIS 中,从 Windows 2012 R2 开始,Kerberos 也是基于会话的。 只有新 TCP 连接上的第一个请求必须由服务器进行身份验证。 后续请求不必包含 Kerberos 票证。

如果你在 IIS 7 及更高版本下运行,则可以使用 authPersistNonNTLM 属性更改此行为。 如果 属性设置为 true,则 Kerberos 将成为基于会话的。 否则,它将基于请求。 由于每次必须包含要发送到服务器的数据量较大,因此性能会降低。 有关详细信息,请参阅 基于请求与基于会话的 Kerberos 身份验证 (或 AuthPersistNonNTLM 参数)

注意

对所有对象盲目使用 Kerberos 身份验证可能不是一个好主意。 使用 Kerberos 身份验证通过条件 GET 请求提取数百个图像,这些请求可能会生成 304 个未修改 的响应,这类似于尝试使用锤子杀死苍蝇。 这种方法也不会提供明显的安全收益。

为什么 Kerberos 委派在我的两个林之间失败,尽管它过去正常工作

请考虑以下情况:

  • 应用程序的用户位于林 A 中的域中。
  • 应用程序位于林 B 中的域中。
  • 林之间存在信任关系。

在这种情况下,Kerberos 委派可能会停止工作,即使它以前曾工作过,并且你尚未对林或域进行任何更改。 Kerberos 身份验证在此方案中仍然有效。 只有委托失败。

出现此问题的原因可能是 Microsoft 在 2019 年 3 月和 2019 年 7 月发布的 Windows Server 安全更新。 这些更新禁用了不受约束的 Kerberos 委派, (能够将 Kerberos 令牌从应用程序委托给后端服务,) 所有新信任和现有信任的林边界。 有关详细信息,请参阅在 Windows Server 中跨传入信任汇报到 TGT 委派

Internet Explorer 功能键

这些键是打开或关闭浏览器的某些功能的注册表项。 这些键位于以下注册表位置:

  • HKEY_USERS\<UserSID>\Software\Microsoft\Internet Explorer\Main\FeatureControl – 如果在用户级别定义
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\ - 如果在计算机级别定义

应在以下位置之一创建功能密钥,具体取决于是要打开还是关闭功能:

  • 针对计算机上的所有用户
  • 仅适用于特定帐户

应在相应的路径下创建这些键。 在键内,应声明名为 iexplorer.exe 的 DWORD 值。 每个键的默认值应为 truefalse,具体取决于功能的所需设置。 默认情况下,功能键 FEATURE_INCLUDE_PORT_IN_SPN_KB908209FEATURE_USE_CNAME_FOR_SPN_KB911149的值为 false。 为了完整性,下面是一个导出注册表的示例,方法是将功能键在 Kerberos 票证中包括端口号更改为 true:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_INCLUDE_PORT_IN_SPN_KB908209]
"iexplore.exe"=dword:00000001

更多信息

Windows 集成身份验证故障排除的诊断页