Windows Authentication with a .NET 6 typed HttpClient

Recently at a client’s site I had to write a new API which calls a downstream web API which was secured with Kerberos authentication, or something, I think. Not sure.

I dug up the code for an existing .NET Framework solution which calls the legacy service. The old code looks like this:

WebRequest myWebRequest = WebRequest.Create(serverUrl);

// Set 'Preauthenticate' property to true. Credentials will be sent with the request.
myWebRequest.PreAuthenticate = true;
myWebRequest.Credentials = new NetworkCredential(user, password);

using (WebResponse myWebResponse = myWebRequest.GetResponse())
using (Stream receiveStream = myWebResponse.GetResponseStream())
    byte[] data = Helper.ReadFully(receiveStream);

I didn’t know what a WebRequest’s NetworkCredential is – but a bit of Fiddler investigation revealed the following header is being sent:

Authorization: Negotiate TlRMTVNTUAADAAAA...

I wasn’t sure how to call this with .NET 6, and it’s not documented in the HttpClient documentation. Fortunately, I eventually found my way to good ol’ Rick Strahl, who has a solution at

In my solution I’m using typed HttpClients which is different to Rick’s custom HttpClient factory implementation. My working solution looks like this:

builder.Services.AddHttpClient<ILegacyClient, LegacyClient>(
    client =>
        client.DefaultRequestHeaders.UserAgent.ParseAdd("My great Api");
        client.BaseAddress = new Uri(builder.Configuration["Clients:Legacy:BaseUri"]);
    }).ConfigurePrimaryHttpMessageHandler(() =>
        var username = builder.Configuration["Clients:Legacy:Username"];
        var password = builder.Configuration["Clients:Legacy:Password"];

        var credentials = new NetworkCredential(username, password);
        return new HttpClientHandler { Credentials = credentials, PreAuthenticate = true };

Easy once you know how.