Search code examples
.netauthenticationhttpntlmntlm-authentication

When the UseDefaultCredentials property of an HttpClientHandler is set to true, how do credentials actually get resolved for a request?


When creating an instance of an HttpClient, you can pass an instance of an HttpClientHandler to configure how you want the client to behave. One of these options is the UseDefaultCredentials property, it's purpose being to control "whether default credentials are sent with requests by the handler". In my personal experience, this purpose often boils down to enabling requests to a service that requires NTLM authentication, just set it to 'true' and it's handled for you.

What I want to understand is how the underlying HTTP handler is able to provide my credentials (i.e. as the logged-in user) without me having to explicitly provide them via a username/password pair. When I look at non-.NET libraries that add support for NTLM authentication (e.g. axios-ntlm for Node.js, python-ntlm for Python), I see that they support the protocol itself but stop short of doing anything to get the credentials of the current user. Ultimately what I want is the magic "just works" experience of NTLM authentication for a client application but without using .NET.

After looking at libraries like I mentioned above, as well as digging through the .NET runtime source (I mean it has to be in there somewhere right?), I have so far been unable to understand how this magic is accomplished.


Solution

  • I think I figured out the basics of how it works. It's essentially a combination of the Win32 SSPI functions AcquireCredentialsHandle and InitializeSecurityContext, the former can provide a handle to the currently logged-in user's credentials and the latter provides the token used during NTLM authentication based on those credentials.

    I haven't put my understanding to the test, but this more or less solves the mystery for me.