I have an internal corporate API that I am calling via an HttpClient from a dotnet core website. The API is hosted in an IIS website that has Windows Authentication turned on. Authentication in the API is performed via this scheme. However the web requests are incredibly slow because the challenge-response process performed by the HttpClient contains large gaps of around 0.4 seconds between the 401 response being received from the API server and the HttpClient sending a subsequent (successful) request with the requisite Authorization header.
The HttpClient is normally injected via an HttpClientFactory but for the sake of clarity here is the equivalent inline code (the problem exists however the HttpClient is instantiated):
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);
}
On the server the logs then show a 0.4 second gap between the 401 response to the initial request and the next request with the Authorization header:
15:56:09.80114 [INF] HTTP "PUT" "/api/Internal/Documents/989898989" responded 401 in 1.4533 ms. User null
15:56:10.17185 [INF] Request starting HTTP/1.1 PUT http://localhost:60491/myapi/api/Internal/Documents/989898989 application/json 750
This is not a network-related issue as the website is local. I have performed exactly the same request via a web browser and the difference between the 401 being received by the browser and the next request is .001 seconds. For the entire PUT request (incorporating both the 401 and 204 responses) from the browser it takes 0.05 seconds and from the HttpClient 0.4 seconds. The performance difference is entirely attributable to the gap in sending the request with the Authorization header.
I can't use the PreAuthenticate flag on the HttpClientHandler as this is Uri-specific and my requests contain IDs that will differ between each one.
Does anyone have any ideas why this would be occurring and, better still, how to get round it?
localhostmight be failing and falling back. Either that or usehttp:-- addinghttpsfor a localhost connection doesn't actually improve your security footing. - John Wu