Skip to content

Incorrect exception message shown during NTLM authentication #28530

@davidsh

Description

@davidsh

Split from #25827

As of .NET Core 2.1, the default HTTP stack is based on SocketsHttpHandler. SocketsHttpHandler uses the GSSAPI for handling HTTP AUTH schemes of 'Negotiate' and 'NTLM'.

On *Nix and OSX machines, this requires installing the GSSAPI support packages for both Kerberos and NTLM. The default docker images for .NET Core do not include the NTLM support package (i.e. gss-ntlmssp). As a result, HttpClient will throw an exception when trying to authenticate against an NTLM server because the NTLM related package is not installed on the machine.

The exception message currently looks like this:

Unhandled Exception: System.ComponentModel.Win32Exception: GSSAPI operation failed with error - An invalid status code was supplied (Unknown error).
at System.Net.Security.NegotiateStreamPal.AcquireCredentialsHandle(String package, Boolean isServer, NetworkCredential credential)
...

This issue will address fixing up the error message text to be more descriptive of the problem and solution.

Repo code
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace NtlmErrorTest
{
    class Program
    {
        static void Main()
        {
            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
                listener.Listen(int.MaxValue);
                var ep = (IPEndPoint)listener.LocalEndPoint;
                var uri = new Uri($"http://{ep.Address}:{ep.Port}/");

                Task.Run(async () =>
                {
                    while (true)
                    {
                        Socket s = await listener.AcceptAsync();
                        var ignored = Task.Run(() =>
                        {
                            using (var ns = new NetworkStream(s))
                            using (var reader = new StreamReader(ns))
                            using (var writer = new StreamWriter(ns) { AutoFlush = true })
                            {
                                while (true)
                                {
                                    while (!string.IsNullOrEmpty(reader.ReadLine())) ;
                                    writer.Write("HTTP/1.1 401 OK\r\nWww-Authenticate: NTLM\r\nContent-Length: 5\r\n\r\nhello");
                                }
                            }
                        });
                    }
                });

                var handler = new HttpClientHandler();
                handler.Credentials = new NetworkCredential("user", "password", "domain");
                using (var client = new HttpClient(handler))
                {
                    Console.WriteLine(uri.AbsoluteUri.ToString());
                    using (HttpResponseMessage response = client.GetAsync(uri).GetAwaiter().GetResult())
                    {
                        Console.WriteLine($"{(int)response.StatusCode} {response.ReasonPhrase}");
                    }
                }
            }
        }
    }
}

Metadata

Metadata

Assignees

Labels

bugos-linuxLinux OS (any supported distro)

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions