【发布时间】:2018-11-22 17:01:27
【问题描述】:
我有一个内部公司 API,我通过 HttpClient 从 dotnet 核心网站调用它。 API 托管在启用了 Windows 身份验证的 IIS 网站中。 API 中的身份验证通过此方案执行。但是,Web 请求非常慢,因为 HttpClient 执行的质询-响应过程在从 API 服务器接收到的 401 响应和 HttpClient 发送具有必要授权标头的后续(成功)请求之间包含大约 0.4 秒的巨大间隙。
HttpClient 通常是通过 HttpClientFactory 注入的,但为了清楚起见,这里是等效的内联代码(问题存在,但是 HttpClient 是实例化的):
using (HttpClient httpClient = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }, true))
{
httpClient.BaseAddress = new System.Uri( "https://localhost:60491/myapi/api/Internal/");
var response = await httpClient.PutAsync(uri, content);
await ValidateResponseAsync(response);
}
然后,在服务器上,日志会显示对初始请求的 401 响应与下一个带有 Authorization 标头的请求之间存在 0.4 秒的间隔:
15:56:09.80114 [INF] HTTP "PUT" "/api/Internal/Documents/989898989" 在 1.4533 毫秒内响应 401。 用户为空
15:56:10.17185 [INF] 请求 启动 HTTP/1.1 PUT http://localhost:60491/myapi/api/Internal/Documents/989898989 应用程序/json 750
这不是与网络相关的问题,因为该网站是本地网站。我通过网络浏览器执行了完全相同的请求,浏览器接收到的 401 与下一个请求之间的差异是 0.001 秒。对于来自浏览器的整个 PUT 请求(包括 401 和 204 响应)需要 0.05 秒,来自 HttpClient 需要 0.4 秒。性能差异完全是由于发送带有 Authorization 标头的请求的差距。
我不能在 HttpClientHandler 上使用 PreAuthenticate 标志,因为这是特定于 Uri 的,而且我的请求包含的 ID 会在每个请求之间有所不同。
有没有人知道为什么会发生这种情况,更好的是,如何解决它?
【问题讨论】:
-
当您通过浏览器访问时,您的登录方式是否与使用 HttpClient 的程序相同(例如,您使用的是服务帐户而不是您的个人登录帐户)?有许多设置可能不同,例如代理设置。此外,请考虑获取证书,因为
localhost的 TLS 验证可能会失败并退回。要么使用http:——为本地主机连接添加https实际上并不能提高你的安全基础。 -
两种情况下的登录名相同。我已将 HttpClientHandler 上的 UseProxy 设置为 false(没有为浏览器设置代理)。 localhost 网站使用受信任的 ISS Express 开发证书。无论如何,我们的测试服务器上也会发生同样的行为,因此它并不特定于我的本地环境,
-
您可能需要设置 WIreshark 并查看流量。将它们并排放置并寻找差异。浏览器可能正在执行某种缓存或有其他一些技巧来提高吞吐量。
标签: c# iis asp.net-core windows-authentication dotnet-httpclient