c# - 尝试使用 HttpClient 检索 AccesToken 时出现错误
问题描述
尝试使用 HttpClient 从 Windows 服务器检索访问令牌时出现错误:
“GSSAPI 操作因错误而失败 - 提供了无效的状态代码(SPNEGO 找不到协商机制)。”
private readonly HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true, AllowAutoRedirect = true }) { Timeout = TimeSpan.FromSeconds(5) };
public async Task<UserAccessToken> GetAuthenticationToken(string accessBrokerHost)
{
try
{
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, $"{accessBrokerHost}/Token")).ConfigureAwait(false);
//accessBrokerHost is HTTP SPN created internally in a windows server
if (!response.IsSuccessStatusCode)
{
throw new BrokerNotAvailableException();
}
return await response.Content.ReadAsAsync<UserAccessToken>().ConfigureAwait(false);
}
}
由于 GSSAPI 操作失败并出现错误而引发 system.ComponentModel.win32Exception - 提供了无效的状态代码(SPNEGO 找不到协商机制)
上面的代码在 Windows 中运行良好,但在 Linux 中运行不正常(我使用的是 Linux Mint)。据我所知,它指的是尝试使用 Kerberos 但没有激活 Kerberos 票证来对 Linux 进行身份验证的问题。
解决方案
最后,我找到了这个问题的解决方案。
解决方案1:
步骤 1. 根据这个,你应该添加
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
第 2 步。由于UseDefaultCredentials = true在这里不起作用,您需要手动将您的网络凭据传递给 HttpClient,如下所示
HttpClient client = new HttpClient(new HttpClientHandler{Credentials = new NetworkCredential("UserName" "Password", "Domain")}
第 3 步。您应该将 HttpRequestMessage 版本更改为
HttpVersion.Version11
.
解决方案 2:您也可以通过将整个应用程序转换为NetcoreApp3.0来解决此问题
推荐阅读
- c# - 使用自定义表数据类型执行存储过程
- asp.net-core - 使用 .NET Core 2.1 实现 Google Open ID Connect 的正确方法是什么?
- javascript - 函数中的异步,等待第一个函数完成,然后再触发下一个函数
- git - 无法从 origin/ 提交文件
到原点/主 - node.js - 带有 Socket.io 和 Express 的 Node.js 聊天应用程序在本地工作,但不在主机上
- android - Android Camera2 onCaptureStarted 回调
- azure-ad-b2c - B2C重置密码
- sql-server - SQLServer 无法创建表,“已经存在”,但它不是 AFAICT
- ruby-on-rails - 查询将数据从表中的一个列值移动到另一个
- javascript - 删除另一个样式标记后通过 js 添加样式标记不起作用