We are using HttpClient to contact REST-services, which we know require NTLM or Negotiate authorization.
The problem is that HttpClient will first contact the service with no authorization (is that called challenge-response?). Client is rejected by the server with a 401, and only then will the client send the request to the server with an Authorization header.
Can we avoid this roundtrip by just adding the Authorization header on the first request?
We are creating out http-client like this (problem is the same with "NTLM" and "Negotiate"):
public Rest.IRestClient Create()
{
var credentials = new CredentialCache { { _uri, "NTLM", CredentialCache.DefaultNetworkCredentials } };
#if NETCOREAPP2_2
var handler = new SocketsHttpHandler { Credentials = credentials, MaxConnectionsPerServer = 100, UseProxy = false };
#elif NET461
var handler = new WebRequestHandler { Credentials = credentials, UnsafeAuthenticatedConnectionSharing = true, MaxConnectionsPerServer = 100, UseProxy = false };
#endif
var httpClient = new HttpClient(handler) { BaseAddress = _uri, Timeout = _timeout };
httpClient.DefaultRequestHeaders.ConnectionClose = false;
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(HostMediaTypeTranslator.GetMediaType(_hostMediaType)));
if (_defaultRequestHeaders != null)
{
foreach (var header in _defaultRequestHeaders)
httpClient.DefaultRequestHeaders.Add(header.Name, header.Value);
}
ServicePointManager.FindServicePoint(_uri).ConnectionLeaseTimeout = 120 * 1000; // Close connection after two minutes
return new Rest.RestClient(httpClient, _hostMediaType);
}
Is it possible to just create our own NTLM or Kerberos token and add it as a header to the http-request?
No, because you are misunderstanding how NTLM works, and in particular the NTLM handshake.
The initial 401 rejection response from the server also contains a challenge/nonce. The subsequent request from the client is requires to contain that challenge, encrypted with the hash of the authenticating account's password.
This is how NTLM works and there is no way to get around it, because you don't (and intentionally can't) know the nonce the server is going to send.
Reference: https://learn.microsoft.com/en-gb/windows/win32/secauthn/microsoft-ntlm