HttpClient、UseDefaultCredentials、Windows 身份验证、.NET Core 2.0+ 控制台应用程序收到 401 Unauthorized

Posted

技术标签:

【中文标题】HttpClient、UseDefaultCredentials、Windows 身份验证、.NET Core 2.0+ 控制台应用程序收到 401 Unauthorized【英文标题】:HttpClient, UseDefaultCredentials, Windows Authentication, .NET Core 2.0+ console application receives 401 Unauthorized 【发布时间】:2018-02-28 14:19:59 【问题描述】:

我正在尝试从 .NET Core 3.0 控制台应用程序进行 HTTP GET 调用。端点需要 Windows 身份验证。该端点是 IIS 上的生产中 .NET Framework 4.5.2 Web API 服务,已被多个客户端应用程序成功使用。

我的测试程序针对net45 框架目标成功。相反,netcoreapp3.0 构建收到 401 Unauthorized。

这是我的方法:

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);

这是我的项目文件。

<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>

运行 .\bin\Debug\net45\HttpClientTest.exe 返回预期的 JSON 结果。

运行 dotnet .\bin\Debug\netcoreapp3.0\HttpClientTest.dll 收到 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

我该如何解决这个问题?

我也尝试了以下变体,输出没有任何变化:

handler.Credentials = CredentialCache.DefaultNetworkCredentials;
handler.Credentials = CredentialCache.DefaultCredentials;
handler.Credentials = new NetworkCredential(username, password, domain);

【问题讨论】:

How to get HttpClient to pass credentials along with the request?的可能重复 我继续遇到这个问题。我现在使用 .NET Core 2.2。 作为记录,我尝试了这个建议作为可能重复的解决方案...***.com/a/48649925/167920 ...没有成功。 在最新版本的 netcoreapp 中试用。 @pavinan 我用 .NET Core 3.0 重新运行了我的实验。结果相同。对于 .NET 4.5,工作正常。对于 .NET Core 3.0,我得到 401 Unauthorized。 【参考方案1】:

这个解决方法对我有用,在创建 HttpClient / Handler 之前添加这个:

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

【讨论】:

此设置已在 .NET 5 中删除。请参阅:docs.microsoft.com/en-us/dotnet/core/run-time-config/networking【参考方案2】:

所以我们在使用 HttpClient 时遇到了同样的问题,但在第一次请求时它是未经授权的,但如果我们再进行一次快速请求调用,它就会顺利通过,并且我们获得了授权。

如果我在 .NET 4.7.1 控制台应用程序上执行此操作,它会完美运行。如果我在 .NET 4.7.1 空 Web 应用程序中执行此操作,它工作正常,只有当我执行 .NET Core 2.x 时才会遇到此问题。

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;

【讨论】:

以上是关于HttpClient、UseDefaultCredentials、Windows 身份验证、.NET Core 2.0+ 控制台应用程序收到 401 Unauthorized的主要内容,如果未能解决你的问题,请参考以下文章

HttpClient

轻松把玩HttpClient之封装HttpClient工具类,插件式配置HttpClient对象

Httpclient4.5.*HttpClient请求,对于新建httpclient实例时保持会话

HttpClient学习整理

httpclient简介说明

httpClient 保持session