.net core HTTPClient with NTLM authentication

548 Views Asked by At

I've got a .net core 7 microservice hosted in docker/kubernetes. Service must invoke external api which use Windows Authentication. Is there any way to use httpclient with ntlm auth inside docker container or maybe other solutions? I was spend several days investigating this problem but didn't find any worked solution. I've tried this approach

builder.Services.AddHttpClient(nameof(TFSClient), client =>
{
    client.BaseAddress = new Uri(clientsOpttions.Url);
})
.ConfigurePrimaryHttpMessageHandler(_ => new HttpClientHandler
{
    Credentials = new CredentialCache {
            {
                new Uri(clientsOpttions.Url), "NTLM", new NetworkCredential(ntlmOpttions.User, ntlmOpttions.Password, ntlmOpttions.Domain)
            }
        }
});

And then resolving it with

var client = _httpClientFactory.CreateClient(nameof(TFSClient));
var result = await client.GetAsync(_allProjectsUri);

But still got 401

2

There are 2 best solutions below

2
Tsonko Stoyanov On

if you haven't found a solution yet. Try adding to the docker file after FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base

RUN apt-get update && apt-get -y install gss-ntlmssp

and also add in client Default Request Headers:

builder.Services.AddHttpClient(nameof(TFSClient), client =>
{
    client.BaseAddress = new Uri(clientsOpttions.Url);
    client.DefaultRequestHeaders.Connection.Add("Keep-Alive");
})
.ConfigurePrimaryHttpMessageHandler(_ => new HttpClientHandler
{
    Credentials = new CredentialCache {
            {
                new Uri(clientsOpttions.Url), "NTLM", new NetworkCredential(ntlmOpttions.User, ntlmOpttions.Password, ntlmOpttions.Domain)
            }
        }
});
0
Николай Солдаткин On

All I was needed to do is use Negotiate instead NTLM

builder.Services.AddHttpClient(nameof(TfsProjectsClient), client =>
{
    client.BaseAddress = new Uri(tfsClientsOpttions.ProjectsUrl);
})

.ConfigurePrimaryHttpMessageHandler((s) =>
{
    return new HttpClientHandler
    {
        PreAuthenticate = true,
        UseProxy = false,
        UseDefaultCredentials = false,

        Credentials = new CredentialCache
         {
            {
                new Uri(tfsClientsOpttions.ProjectsUrl), "Negotiate", new NetworkCredential(credentialOpttions.User, credentialOpttions.Password, credentialOpttions.Domain)
            }
         }
    };
});