【问题标题】:ASP.NET Core 3.0: How to forward an existing authentication to another request - double hop problem?ASP.NET Core 3.0:如何将现有身份验证转发到另一个请求 - 双跳问题?
【发布时间】:2023-11-08 07:05:01
【问题描述】:

我有以下场景(所有应用程序和服务都在 Windows 上使用 asp.net core 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);

在 WebServiceA 中,调用被正确接收并通过了身份验证: HttpContext.User.Identity.IsAuthenticated 为真,HttpContext.User.Identity.Name 为 AppUser。

为了能够处理请求,WebServiceA 必须向 WebServiceB 发送另一个请求。 此请求还必须通过 AppUser 身份验证

目前我正在使用以下代码创建向 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(发送请求)

我认为 DefaultNetworkCredentials 始终是经过身份验证的用户的那些。

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

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

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

setspn -S HTTP/ServerA.domain domain\WebUser

还尝试过: setspn -a WebServiceA/WebUser domain\WebUser

但没有成功。

经过三天的网络研究和尝试,我头晕目眩…… 如何让 UserCredentials 进入第二个请求? 还是因为(可能是错误的?)AD 配置 (SPN),WebService 总是默默地获取启动服务的用户的凭据?

感谢每一个提示!

史蒂芬

【问题讨论】:

  • 以用户身份在服务器上运行任何东西都需要所谓的模拟。我从来没有在.net core 中这样做过,所以这就是评论的原因。找到this one,它可能会给你一个方向。
  • 你有没有让这个工作?我也有同样的问题
  • 已经有一段时间了,但为了完整起见:我让它与模拟一起工作:WindowsIdentity.RunImpersonated(windowsUserIdentity.AccessToken, () => { result = this.SendRequestHttpGetAsync(uri); }); @WiktorZychla:您评论中的链接显示了如何做到这一点。如果您将评论作为答案发布,我会将其标记为已接受。

标签: c# kerberos windows-authentication asp.net-core-3.0


【解决方案1】:

评论中 OP 接受的答案涉及模仿。根据这个blog entry,可以在.Net Core 中使用WindowsIdentity.RunImpersonated

// 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...  
});

【讨论】:

    最近更新 更多