当应用程序托管在 IIS(协商 + NTLM)上时,两个 401(Unauth)响应后跟一个 200(OK)

Two 401 (Unauth) responses followed by one 200 (OK) when app hosted on IIS (Negotiate + NTLM)

我的情况与Eradicating 401 "Unauthorised" responses followed by 200 "Ok" responses

中提到的非常相似

但它没有为我们提供足够的响应。

我有一个简单的 GET 请求示例,当由 运行 在没有 IIS 的情况下在本地 api 发出时,会产生一个响应,即 OK/200: Fiddler trace here

但是当它托管在 IIS 上时 returns 两个 401 和一个 200:Fiddler trace here

这里还有 IIS 网络身份验证配置:Config

在调用 API 的应用程序中,我们检查 200 响应代码,我们在代码中收到断断续续的 200/401,这使得验证非常烦人,请求在每种情况下都完美通过。

如能提供任何帮助,我们将不胜感激,如果这是 NTLM 身份验证的工作方式,是否还有其他方法可以验证对 api 的调用最终是否成功?最后,这就是我们想在调用方应用程序中了解的内容。

如一些文章所述,我尝试在 IIS -> 身份验证 -> 提供程序列表中将 NTLM 移动到提供程序列表的顶部(在底部协商),但这并没有解决这个问题

感谢观看。

编辑:如果是 IIS,这是 fiddler 中的请求 headers:

  1. 带有 401 的请求 1:img
  2. 带有 401 的请求 2:img
  3. 请求 2 200 : img

编辑 2:根据 MisterSmith 的回答和其他一些阅读资料,这就是 NTLM 身份验证的工作方式,更多的是关于我们如何处理应用程序中的响应。

就我而言,我正在使用 .net 核心 HttpClient 库发出请求,它处理 NTLM 身份验证的方式可能存在问题。 如果有人对此感兴趣,可以在这里找到:

这基本上就是它的工作原理 - 用户尚未成功验证握手的前 2 个请求,因此 401 是预期的并且完全合理。

如果您可以(以某种方式)让浏览器始终发送身份验证 headers(仅针对此站点!),这将删除一个 401,而另一个是不可避免的,而无需完全放弃 NTLM。

本地 运行 和 IIS 中的 运行 之间的区别在于拦截和修改 headers 的身份验证模块。如果您要在 IIS 中关闭身份验证,它也会 return 单个 200 响应(出于显而易见的原因,这是一个测试而不是解决方案)。

200/401 in the code which makes the validation really annoying

401、401、200 都将按顺序来自同一个套接字。如果您查看 401 上的响应 headers,您应该能够确认哪些是预期的。此外,IIS 在访问日志和 IIS 代码 运行 的请求上下文中可见 sub-status。很确定您可以根据子状态条件以及 headers 重写 - 这可能有助于区分请求作为最后的手段?

is there any other way to validate the call to the api was successful eventually

NTLM 使用保活套接字发送多个请求 - 只需继续从套接字读取数据直到合理超时并存储收到的最终响应代码。

moving NTLM to the top of the providers list

我不确定更改顺序会有什么影响,但我突然想到了一些事情 - system.webServer/security/authentication/windowsAuthentication 部分通常被锁定,因此 web.config 级别的更改将被忽略并需要成为 applied at the machine.config level.