C# HttpClient使用Windows身份验证时速度非常慢

C# HttpClient使用Windows身份验证时速度非常慢,c#,iis,asp.net-core,windows-authentication,dotnet-httpclient,C#,Iis,Asp.net Core,Windows Authentication,Dotnet Httpclient,我有一个内部公司API,我通过一个来自dotnet核心网站的HttpClient调用它。API托管在启用了Windows身份验证的IIS网站中。API中的身份验证通过此方案执行。但是,web请求的速度非常慢,因为HttpClient执行的质询响应过程在从API服务器接收到401响应和HttpClient发送后续(成功)请求以及所需的授权标头之间存在大约0.4秒的巨大间隔 HttpClient通常通过HttpClientFactory注入,但为了清楚起见,这里是等效的内联代码(尽管HttpClie

我有一个内部公司API,我通过一个来自dotnet核心网站的HttpClient调用它。API托管在启用了Windows身份验证的IIS网站中。API中的身份验证通过此方案执行。但是,web请求的速度非常慢,因为HttpClient执行的质询响应过程在从API服务器接收到401响应和HttpClient发送后续(成功)请求以及所需的授权标头之间存在大约0.4秒的巨大间隔

HttpClient通常通过HttpClientFactory注入,但为了清楚起见,这里是等效的内联代码(尽管HttpClient被实例化,但问题仍然存在):

在服务器上,日志显示对初始请求的401响应与下一个带有授权标头的请求之间有0.4秒的间隔:

15:56:09.80114[INF] HTTP“PUT”“/api/Internal/Documents/989”在1.4533毫秒内响应401。 用户空值

15:56:10.17185[INF]请求 启动HTTP/1.1 PUT 应用程序/json 750

这不是一个与网络相关的问题,因为该网站是本地的。我通过web浏览器执行了完全相同的请求,浏览器接收到的401与下一个请求之间的差异为.001秒。对于来自浏览器的整个PUT请求(包括401和204响应),需要0.05秒,来自HttpClient的需要0.4秒。性能差异完全归因于使用授权标头发送请求时存在的差距

我不能在HttpClientHandler上使用PreAuthenticate标志,因为这是特定于Uri的,并且我的请求包含的ID在每个请求之间都会有所不同


有人知道为什么会发生这种情况,更好的是,知道如何避免这种情况吗?

您不应该为每个请求创建一个新的HttpClient,这正是您的using语句所做的

HttpClient旨在实例化一次,并在应用程序的整个生命周期中重用


你不能设置一个更快的超时吗?


我假设它以某种方式被编码到请求中,并在客户端内部使用。我已经了解到.net Core httpClient在2.0中速度非常慢,在2.1中速度要快得多,您还可以检查代理设置,因为这在.net Core httpClient中可能是个问题。

默认情况下
HttpClientHandler
默认启用了属性
UseProxy
。我遇到过类似的情况,它试图使用系统默认设置(设置为“自动配置代理”)查找代理,这增加了显著的延迟


当您初始化
HttpClientHandler
时,将
UseProxy
设置为false,这可能会使问题消失。

正如我在问题中提到的,这不是网站中运行的实际代码。HttpClient实际上是通过DI设置的IHttpClientFactory注入的,因此不会每次都实例化。为了清晰起见,我仅使用了该代码片段来显示针对HttpClientHandler设置的属性。无论是每次按照代码块实例化还是通过工厂实例化,都会导致相同的性能问题。我的直觉是尝试使用Post而不是Put,我在使用Put时也遇到过类似的问题。希望此帮助当您通过浏览器访问时,您是否以与使用HttpClient的程序相同的方式登录(例如,您是否使用服务帐户而不是个人登录帐户)?可能存在许多不同的设置,例如代理设置。此外,考虑获得证书,因为 LoalHoals的TLS验证可能失败和回落。或者使用
http:
——为本地主机连接添加
https
,实际上并不能提高您的安全性。这两种情况下的登录都是相同的。我已将HttpClientHandler上的UseProxy设置为false(没有为浏览器设置代理)。localhost网站使用受信任的ISS Express开发证书。在任何情况下,我们的测试服务器上也会发生同样的行为,因此这不是我的本地环境所特有的,您可能需要设置WIreshark并观察流量。将它们并排放置,寻找差异。浏览器可能正在执行某种缓存或使用其他一些技巧来提高吞吐量。但它没有超时,因此我看不出更改Timeout属性有何帮助?请求成功,只是速度很慢。我使用的是core 2.1,所以也不是这样。你能看到Telerik Fiddler或Wireshark在网络上发生了什么吗?嗨,Scott,谢谢,我原以为这已经解决了问题,但后来看到在开发环境中设置了一个标志来授权任何请求,所以在最初的请求中没有401被发回。当我删除此项并返回401时,在接收401和发出带有授权标头的成功请求之间再次出现0.4秒的延迟。
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);
}