.NET Core SPNEGO 身份验证与 HttpClient
.NET Core SPNEGO Auth with HttpClient
我目前正在编写一个简单的基于 .NET Core 的客户端,用于通过 WebHCat 与 Hadoop 集群交互,我正在尝试弄清楚如何使用 SPNEGO 进行身份验证,就像在 curl 或 Powershell Core 中一样。
使用 Curl 我可以像这样查询 WebHCat 的状态端点:
curl "http://10.2.0.9:50111/templeton/v1/status" --negotiate -k -u :
同样的请求也可以在Powershell Core中执行:
$client = New-Object System.Net.WebClient;
$client.UseDefaultCredentials = $true;
$client.DownloadString("http://10.2.0.9:50111/templeton/v1/status");
然而,当涉及到 运行在与集群位于同一服务器上的 .NET Core 项目中执行以下操作时:
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace testauth
{
class Program
{
static async Task Main(string[] args)
{
var host = "http://10.2.0.9:50111/templeton/v1/status";
var handler = new HttpClientHandler
{
UseDefaultCredentials = true,
AllowAutoRedirect = true,
};
using (var client = new HttpClient(new LoggingHandler(handler)))
{
var res = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, host));
}
}
}
}
我收到以下错误:
Unhandled Exception: System.ComponentModel.Win32Exception: GSSAPI operation failed with error - An invalid status code was supplied (Server not found in Kerberos database).
at System.Net.NTAuthentication.GetOutgoingBlob(Byte[] incomingBlob, Boolean throwOnError, SecurityStatusPal& statusCode)
客户端是 运行ning .NET Core 2.1,所以正如 this issue 中提到的,我应该能够将默认凭据传递给处理程序,它会按预期工作。
我也试过用 C# 编写我在 PowerShell Core 中使用的相同代码,尽管代码相同,但它仍然抛出相同的错误?
我能提供的唯一其他细节是 Kerberos 连接到只有一个用户的 Active Directory 实例,所有这些请求都是 运行 在使用 [=14] 创建该用户的票证之后=].
我设法找到了修复方法。 With ASP.NET Core 2.1 they introduced a new SocketsHttpHandler
默认用于请求。这意味着在某些平台上,它可能会覆盖我的请求中提供的 HttpHandler
,因此默认为您应该使用的套接字处理程序:
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
这解决了我的请求。
我目前正在编写一个简单的基于 .NET Core 的客户端,用于通过 WebHCat 与 Hadoop 集群交互,我正在尝试弄清楚如何使用 SPNEGO 进行身份验证,就像在 curl 或 Powershell Core 中一样。
使用 Curl 我可以像这样查询 WebHCat 的状态端点:
curl "http://10.2.0.9:50111/templeton/v1/status" --negotiate -k -u :
同样的请求也可以在Powershell Core中执行:
$client = New-Object System.Net.WebClient;
$client.UseDefaultCredentials = $true;
$client.DownloadString("http://10.2.0.9:50111/templeton/v1/status");
然而,当涉及到 运行在与集群位于同一服务器上的 .NET Core 项目中执行以下操作时:
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace testauth
{
class Program
{
static async Task Main(string[] args)
{
var host = "http://10.2.0.9:50111/templeton/v1/status";
var handler = new HttpClientHandler
{
UseDefaultCredentials = true,
AllowAutoRedirect = true,
};
using (var client = new HttpClient(new LoggingHandler(handler)))
{
var res = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, host));
}
}
}
}
我收到以下错误:
Unhandled Exception: System.ComponentModel.Win32Exception: GSSAPI operation failed with error - An invalid status code was supplied (Server not found in Kerberos database).
at System.Net.NTAuthentication.GetOutgoingBlob(Byte[] incomingBlob, Boolean throwOnError, SecurityStatusPal& statusCode)
客户端是 运行ning .NET Core 2.1,所以正如 this issue 中提到的,我应该能够将默认凭据传递给处理程序,它会按预期工作。
我也试过用 C# 编写我在 PowerShell Core 中使用的相同代码,尽管代码相同,但它仍然抛出相同的错误?
我能提供的唯一其他细节是 Kerberos 连接到只有一个用户的 Active Directory 实例,所有这些请求都是 运行 在使用 [=14] 创建该用户的票证之后=].
我设法找到了修复方法。 With ASP.NET Core 2.1 they introduced a new SocketsHttpHandler
默认用于请求。这意味着在某些平台上,它可能会覆盖我的请求中提供的 HttpHandler
,因此默认为您应该使用的套接字处理程序:
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
这解决了我的请求。