Skip to content

NTLM authentication not working in Linux based environment #101058

Closed
dotnet/dotnet-api-docs
#10359
@jondoe69420

Description

@jondoe69420

Description

I need to send an http request to a server which uses Windows authentication. I wrote the following code to try and send just any request to my server.

var handler = new HttpClientHandler 
{
    PreAuthenticate = true,
    UseProxy = false,
    UseDefaultCredentials = false,
    Credentials = new CredentialCache
    {
        {
            new Uri("http://otherapi"), "Negotiate", new NetworkCredential("username", "password")
        }
    }
}

using var client = new HttpClient(handler);
var stringContent = new StringContent("{}", Encoding.UTF8, "application/json");
using var request = new HttpRequestMessage(HttpMethod.Post, "http://otherapi/api/endpoint");
request.Content = stringContent;
using var res = await client.SendAsync(request);
Console.WriteLine($"{res.StatusCode}");

When running the above code on a Windows machine, everything works as expected, and BadRequest gets printed to the console ( which is what I expect to happen when sending an invalid json request ).

The problem is, I need to run this code on a Linux based machine, and when running it on an Ubuntu 22 machine (as well as the official aspnet docker image), it fails and prints out to the console Unauthorized, which means the windows authentication didn't work.

I also tried it with

Credentials = new CredentialCache
    {
        {
            new Uri("http://otherapi"), "NTLM", new NetworkCredential("username", "password")
        }
    }

with no success.

I opened up Wireshark on my windows machine to try and figure out whats going on. I saw that the client initially sends a POST request to the server, and then the server responds with a 401, and the following headers

WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM

After that I saw that the client sent the same request again, this time with an Authorization header, which from what I understand, is the correct behaviour. After that the request continues as expected.

The problem is, when I open Wireshark on my Ubuntu machine, I see that after the server responded with the first 401, the client just stops sending requests for some reason.

Reproduction Steps

Run the following code in a Linux machine

var handler = new HttpClientHandler 
{
    PreAuthenticate = true,
    UseProxy = false,
    UseDefaultCredentials = false,
    Credentials = new CredentialsCache
    {
        {
            new Uri("http://otherapi"), "Negotiate", new NetworkCredential("username", "password")
        }
    }
}

using var client = new HttpClient(handler);
var stringContent = new StringContent("{}", Encoding.UTF8, "application/json");
using var request = new HttpRequestMessage(HttpMethod.Post, "http://otherapi/api/endpoint");
request.Content = stringContent;
using var res = await client.SendAsync(request);
Console.WriteLine($"{res.StatusCode}");

Expected behavior

BadRequest printed out on both Linux and Windows

Actual behavior

Unauthorized printed out on Linux,
BadRequest printed out on Windows.

Regression?

No response

Known Workarounds

No response

Configuration

I tried both .NET 7 and .NET 8

Ran on Windows 10
Linux was ran on Ubuntu 22 and the official aspnet docker image

Other information

No response

Metadata

Metadata

Assignees

Labels

area-System.Net.HttpdocumentationDocumentation bug or enhancement, does not impact product or test code

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions