21

I am trying to make an HTTP GET call from a .NET Core 3.0 console application. The endpoint expects Windows Authentication. The endpoint is an in-production .NET Framework 4.5.2 Web API service on IIS successfully used by several client applications.

My test program succeeds for a net45 framework target. In contrast, the netcoreapp3.0 build receives a 401 Unauthorized.

Here is my method:

using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

static async Task<string> Get(string serverUri, string requestUri)
{
    var handler = new HttpClientHandler() { UseDefaultCredentials = true };
    var client = new HttpClient(handler) { BaseAddress = new Uri(serverUri) };
    return await client.GetStringAsync(requestUri);
}

Here is my project file.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFrameworks>net45;netcoreapp3.0</TargetFrameworks>
  </PropertyGroup>
  <ItemGroup Condition="'$(TargetFramework)' == 'net45'">
    <PackageReference Include="System.Net.Http" Version="4.3" />
  </ItemGroup>
</Project>

Running .\bin\Debug\net45\HttpClientTest.exe returns the expected JSON result.

Running dotnet .\bin\Debug\netcoreapp3.0\HttpClientTest.dll receives a 401 Unauthorized.

Unhandled exception. System.AggregateException: One or more errors occurred. (Response status code does not indicate success: 401 (Unauthorized).)
    ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized).
    at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
    at System.Net.Http.HttpClient.GetStringAsyncCore(Task`1 getTask)
    at ConsoleApp1.Program.Get(String serverUri, String requestUri) in C:\temp\coreapp3\Program.cs:line 16
    --- End of inner exception stack trace ---
    at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
    at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
    at System.Threading.Tasks.Task`1.get_Result()
    at ConsoleApp1.Program.Main(String[] args) in C:\temp\coreapp3\Program.cs:line 22

How do I fix this?

I have also tried the variations below, without any change in output:

handler.Credentials = CredentialCache.DefaultNetworkCredentials;
handler.Credentials = CredentialCache.DefaultCredentials;
handler.Credentials = new NetworkCredential(username, password, domain);
Wallace Kelly
  • 15,565
  • 8
  • 50
  • 71

2 Answers2

1

This workaround works for me add this before creating HttpClient / Handler:

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
Anh Bui
  • 283
  • 1
  • 8
  • 1
    This setting was removed in .NET 5. See: https://learn.microsoft.com/en-us/dotnet/core/run-time-config/networking – 4e 69 63 6b Jan 11 '22 at 15:20
-1

So we are running into the same issue with HttpClient, but on the first request it is unauthorized, but if we do a another quick request call, it goes through just fine, and we get authorized.

If I do this on a .NET 4.7.1 console app, it works perfect. If I do it in a .NET 4.7.1 empty web app, it works fine, only if I do .NET Core 2.x do we get this issue.

var result = string.Empty;
var responseMessage = _client.GetAsync(url).Result;

if (responseMessage.IsSuccessStatusCode)
{
    result = await responseMessage.Content.ReadAsStringAsync();
}
else
{
    var responseMessage2 = _client.GetAsync(url).Result;

    if (responseMessage2.IsSuccessStatusCode)
    {
        result = await responseMessage2.Content.ReadAsStringAsync();
    }
}

return result;
Nkosi
  • 235,767
  • 35
  • 427
  • 472
FunnyNjK
  • 112
  • 1