7

Update Turns out all I needed to do was upgrade to .NET Core 2.1! Thanks for the solutions everyone!


I have a .NET Core 2.0 Console App and need to make a web request to an API which uses Windows Authentication (NTLM specifically). It's an internal API in my company and I'm having a hard time trying to connect to it successfully, keep getting 401s.

My research

I checked out on SO:

I then found this issue which was raised in the .NET Core github and it says it has been resolved. I tried following a code example there but still did not work.

My code

Here is what I have so far, I changed the Uri as it's hosted on the company network, but I hope this will be sufficient to run locally.

public class NTLMProxy
{
    private readonly HttpClient _httpClient;

    public NTLMProxy()
    {
        _httpClient = CreateHttpClientWithNTLM();
    }

    public Task<HttpResponseMessage> GetUsers()
    {
        var httpRequest = new HttpRequestMessage(HttpMethod.Get, _httpClient.BaseAddress);

        return _httpClient.SendAsync(httpRequest);
    }

    public HttpClient CreateHttpClientWithNTLM()
    {
        var uri = new Uri("http://ntlmservice.com/services/api/foo");
        var credentialsCache = new CredentialCache { { uri, "NTLM", CredentialCache.DefaultNetworkCredentials } };
        var handler = new HttpClientHandler { Credentials = credentialsCache };
        var httpClient = new HttpClient(handler) { BaseAddress = uri };
        httpClient.DefaultRequestHeaders.ConnectionClose = false;
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        ServicePointManager.FindServicePoint(uri).ConnectionLeaseTimeout = 120 * 1000;  // Close connection after two minutes

        return httpClient;
    }
}

If you have any ideas / suggestions, please let me know.

Troy Poulter
  • 677
  • 1
  • 8
  • 29
  • 2
    Why not use .NET Core 2.1 instead of 2.0? Even your linked example states that it works in .NET 2.1. – Uwe Keim Dec 10 '18 at 05:30
  • 2
    I realised that just after I posted the question (woops), updating Visual Studio now and will try it out using .Net Core 2.1 and will update on progress. – Troy Poulter Dec 10 '18 at 05:35
  • 1
    Is NTLM and windows authenthenthication the same thing? This is what works for me for windows authenthication HttpClient = new HttpClient(new HttpClientHandler {UseDefaultCredentials = true}). I don't have the CredentialsCache thing, not sure if the code is doing the same thing in the background. – Georgi Georgiev Dec 10 '18 at 07:18
  • @GeorgiGeorgiev people use both to mean Windows Authentication – Panagiotis Kanavos Dec 10 '18 at 13:40
  • @Trozza the long-term support version is 2.1, not 2.0. 2.0 is already unsupported. You should move to 2.1 anyway – Panagiotis Kanavos Dec 10 '18 at 13:43

1 Answers1

6

For .NET Core 2.1 I have this implementation working, using a HttpClientFactory

In ConfigureServices(IServiceCollection services) in the class Startup I have this named HttpClient registration:

        services.AddHttpClient("myName").ConfigurePrimaryHttpMessageHandler(_ => new HttpClientHandler
        {
            Credentials = new CredentialCache { 
                {
                    new Uri("url"), "NTLM", new NetworkCredential("username", "password", "domain")
                }
            }
        });

At the location where you need the HttpClient just resolve it like this:

var client  = _httpClientFactory.CreateClient("myName"); 

Don't forget to inject the factory in the constructor.

public class MyClass{
    private readonly IHttpClientFactory _httpClientFactory;

    public MyClass(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }
}

Good luck!

321X
  • 3,153
  • 2
  • 30
  • 42