ASP.NET Core 3.0:如何将现有身份验证转发到另一个请求 - 双跃点问题?



我有以下场景(所有应用程序和服务都在Windows上使用 asp.net 核心3.0(:

我有一个在 AppUser 上下文中运行的客户端应用程序。它使用 HttpClient 向在 WebUser 上下文中运行的 WebServiceA 发送请求。 该请求使用 Windows 身份验证。

var credentialsCache = new CredentialCache { { uri, "Negotiate", CredentialCache.DefaultNetworkCredentials } };
var handler = new HttpClientHandler { Credentials = credentialsCache };
var httpClient = new HttpClient(handler);

在 WebService A 中,正确接收调用并进行身份验证:HttpContext.User.Identity.IsAuthenticated是真的,HttpContext.User.Identity.Name是AppUser。

为了能够处理请求,WebServiceA 必须向 WebServiceB 发送另一个请求。此请求还必须作为应用程序用户进行身份验证

目前,我使用以下代码来创建向WebServiceB发出请求的HttpClient:

var credentialsCache = new CredentialCache { { uri, "Negotiate", CredentialCache.DefaultNetworkCredentials } };
HttpClientHandler handler = new HttpClientHandler
{
Credentials = credentialsCache,
UseDefaultCredentials = true
};
HttpClient httpClient = new HttpClient(handler);

问题是,调用始终被验证为 WebUser(运行服务(,而不是 AppUser(发送请求(。

我认为默认网络凭据始终是经过身份验证的用户的凭据。

如何(从 WebRequest 中(将另一个 WebRequest 发送到另一个 Web 服务,该 Web 服务已通过提交原始请求的同一用户进行身份验证? 有没有办法将身份验证从一个 Web 服务传递到另一个 Web服务?

关于Kerberos和AD: WebServiceA 和 WebServiceB 在同一域中的不同服务器上运行。它们不是托管在 IIS 中,而是托管在 Windows 服务中。

我尝试按此处所述设置 SPN: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-3.0&tabs=visual-studio

setspn -S HTTP/ServerA.domain domainWebUser

还尝试过:setspn -a WebServiceA/WebUser domainWebUser

但没有成功。

经过三天的网络研究和尝试,我的头在旋转...... 如何将用户凭据获取到第二个请求中? 还是因为(可能是错误的?AD 配置 (SPN( Web 服务始终以静默方式获取启动服务的用户的凭据?

我很感激每一个提示!

斯特菲

OP 在注释中接受的答案涉及模拟。根据此博客条目,可以使用WindowsIdentity.RunImpersonated在.Net Core中

// The user to be impersonated
var userToImpersonate = (WindowsIdentity)HttpContext.User.Identity;
// Impersonating the current Windows user [HttpContext.User.Identity]...
var result = await WindowsIdentity.RunImpersonated(
userToImpersonate.AccessToken, async () =>
{
// This time WindowsIdentity.GetCurrent() will retrieve the impersonated
// user with its claims...
var impersonatedUser = WindowsIdentity.GetCurrent().Name;
// Your business logic code here...  
});

最新更新