排查 Windows 集成身份验证失败情况可能很困难,尤其是在处理 Kerberos 凭据委派时。 尽管提供了有关如何确保 Internet Information Services(IIS)正确配置以使用 Windows 集成身份验证和选择性地使用凭据委派的详细 清单 ,但本文专门针对以下方案:
- 可以从客户端计算机登录到目标网站,但不确定是使用 NTLM 还是 Kerberos 作为身份验证机制。
- 你可以登录到目标网站,但在输入用户名和密码组合后,系统才会提示你登录。
- 可以在前端服务器上访问目标网站,但在启动操作时会失败,该操作要求前端服务器使用经过身份验证的用户凭据调用后端 HTTP 终结点。
在本文中,请考虑以下布局:
客户端 1 是已加入域的工作站或笔记本电脑,假设用户将从中启动所有连接尝试。
Web-serv1 是托管 ASP.NET(在 .NET Framework)网站上的前端 IIS 服务器,它使用 Windows 集成身份验证并使用服务帐户的标识: domain\serviceaccount 运行。
Web-serv2 是后端 Web 服务器,该服务器还托管 ASP.NET(在 .NET Framework)站点上,该站点将公开前端应用程序的 API 终结点。 它还配置为允许使用 Windows 集成身份验证并在使用 域\serviceapiaccount 作为应用程序池标识的应用程序池中执行请求。
为了简化这些方案的数据收集,而不依赖于外部数据收集工具(例如 Fiddler 或 WireShark)(由于三台计算机之间的连接可能使用 HTTPS,因此将加密它们之间的所有交换),请使用 ASP.NET 自包含页中的 两个独立诊断页来排查 IIS 上的 Windows 集成身份验证问题。
故障排除页面
这两个页面在 web 窗体 ASP.NET 编码。 它们旨在捆绑一个文件中页面的代码和标记,该文件可复制到要尝试故障排除的 Web 应用程序的根目录,而无需编译或部署。 页面包括:
WhoAmI.aspx - 此页面允许转储身份验证相关信息,例如:
用于访问目标站点的身份验证方法。 如果该方法基于 Windows 集成身份验证的 Negotiate 提供程序,则页面会显示 Kerberos 或 NTLM 是否用于对用户进行身份验证。
运行托管站点的应用程序池的帐户的标识。
经过身份验证的用户的模拟级别。 如果 Kerberos 用于身份验证和不允许的凭据委派,则模拟级别将标记为委托。 否则,在约束委派或简单模拟的情况下,它将标记为模拟。
经过身份验证的用户和用户所属的组的标识。
执行页面代码的帐户的标识(可以是经过身份验证的用户或应用程序池用户,具体取决于 模拟 设置)。
从 IIS 服务器变量恢复的WhoAmI.aspx页中请求的请求标头的所有值。
ScrapperTest.aspx - 此页面用于 WhoAmI.aspx 页,允许从前端服务器发出的请求定向到后端服务器上的任何 URL。 该页面提供一个 UI 界面,允许用户:
输入页面应尝试加载的后端服务器资源的所需 URL。
确定他们在加载 ScrapperTest.aspx 页面时是否进行身份验证,以及是否已通过身份验证,以及他们进行身份验证的用户身份。
在确实对用户进行身份验证的情况下,复选框允许尝试在尝试加载 URL 文本框中指示的后端资源时重复使用用户的凭据。
如何部署
由于这两个页面都是自包含的,因此唯一需要的是:
- 从 GitHub 存储库下载页面。
- 将 WhoAmI.aspx 页或这两个页面复制到 IIS 中运行的目标 Web 应用程序的根目录。
- 根据要访问的页面,向追加 /WhoAmI.aspx 或 /ScrapperTest.aspx 的网站 URL 发出请求。
使用情况
第一个使用方案是尝试确定使用哪种身份验证方法访问 IIS 上托管的给定网站或 Web 应用程序。 对于此页,可以向 以前部署到网站的WhoAmI.aspx 页面发出请求。
在第一个请求中,页面将显示身份验证信息。 如果使用 Windows 集成身份验证的 Negotiate 提供程序,它还将列出所使用的身份验证协议:Kerberos 或 NTLM。
在将 Negotiate 用作 Windows 集成身份验证提供程序的方案中的后续请求将仅显示 身份验证类型旁边的基于 会话的标签。 有关详细信息,请参阅基于请求的与基于会话的 Kerberos 身份验证(或 AuthPersistNonNTLM 参数)。
所有其他身份验证信息(如应用程序池用户、经过身份验证的用户、执行用户详细信息和传入请求的标头)都将在每个请求上显示。
WhoAmI.aspx页面还显示底部的一个小窗体。 此表单允许向服务器发出 POST
请求,以测试发出这些类型的请求时浏览器的行为方式。 如果页面处于空闲状态超过 60 秒,则传输控制协议 (TCP) 连接用于将页面下载到浏览器,由服务器进行身份验证将因不活动而断开。 因此,发出 POST
请求时,会打开新的 TCP 连接,并且必须重新进行身份验证。 请求有一个微妙之处 POST
:
- 浏览器首先发送 HTTP
POST
请求标头。 - 然后,它会发出请求正文
POST
,其中包含从页面上显示的 HTTP 窗体上各种输入字段捕获的信息。
如果浏览器在发送 POST
请求的标头后没有等待,而是直接在未经身份验证的连接上发送正文,则可能会出现以下问题:
- 服务器接收
POST
请求标头,并且由于连接未通过身份验证(假设使用了 Windows 集成身份验证或其他基于质询的身份验证),因此会发出具有适当身份验证响应 HTTP 标头的 401 响应(WWW-Authenticate
)。 - 在此期间,浏览器已发送
POST
请求正文,然后再从服务器接收 401 响应。 - 然后,服务器在客户端指示需要身份验证的连接上收到未经身份验证
POST
的请求正文。 - 这会导致服务器中断基础 TCP 连接,并且浏览器可能会显示“网页不可用”消息。
ScrapperTest.aspx页用于测试从前端服务器到后端服务器终结点的凭据方案的委派。 从客户端浏览器请求页面后,它将提供一个允许:
- 输入前端服务器应连接到的后端终结点 URL。
- 验证用户是否已在前端上进行身份验证,以及用于连接到前端服务器的用户名。
- 决定(如果身份验证用于访问 ScrapperTest.aspx 页),是否应将经过身份验证的用户的凭据与请求一起传递给后端服务器(如果可能模拟和委派)。
选择“报废页”按钮后,ScrapperTest.aspx页的代码将发出GET
针对所指示的目标 URL 的请求。 如果选中了“使用凭据”复选框,并且需要身份验证才能访问指定的后端终结点,则经过身份验证的用户凭据也用于发出请求。 如果请求成功,结果会显示在页面的文本区域控件中作为收到的响应的原始 HTTP 输出。
我们设想的一种使用方案是将 ScrapperTest.aspx 页和 WhoAmI.aspx 页放置在将在后端服务器上联系的 ASP.NET 应用程序中。 因此,ScrapperTest.aspx页恢复的 HTTP 响应将是后端执行时WhoAmI.aspx页的 HTML 输出。 然后,可以评估此输出,以了解如何在后端对请求进行身份验证以及使用了哪些帐户。
详细信息
若要进一步了解使用 Kerberos 的 Windows 集成身份验证设置,请参阅: