将应用程序池凭据用于 WebClient 请求

Bla*_*ell 4 .net c# security asp.net-web-api

我想使用应用程序池凭据来避免来自 Web API 方法的双跳问题。但是,我不希望模拟所有请求,而只是模拟这一特定请求。代码目前看起来像这样:

[Route("api/mycontroller/mymethod")]
public string GetDataFromOtherInternalSystem(int id)
{
  var client = new WebClient ( Credentials = CredentialCache.DefaultNetworkCredentials);

return client.DownloadString('http://internaldomain/api/method/id')

}
Run Code Online (Sandbox Code Playgroud)

根据我对MSDN 的理解,用户上下文是该浏览器会话的登录用户(即我的帐户通过 Active Directory 而不是应用程序池的帐户)。

DefaultNetworkCredentials 返回的凭据表示应用程序在其中运行的当前安全上下文的身份验证凭据。对于客户端应用程序,这些通常是运行该应用程序的用户的 Windows 凭据(用户名、密码和域)。对于 ASP.NET 应用程序,默认网络凭据是登录用户或被模拟用户的用户凭据。

这会产生双跳问题,如果请求完全来自作为服务帐户的 Web 应用程序(无需我即时构建凭据),则可以消除该问题。

关于如何在不指定用户凭据的情况下模拟应用程序池的任何想法,如下所示:

var cred = new NetworkCredential("myusername", "mypassword")
Run Code Online (Sandbox Code Playgroud)

我再次尝试避免为 Kerberos 或 CORS 正确设置其他 Web 服务。

zYz*_*zil 6

这可以通过将空指针 (IntPtr.Zero) 传递给 WindowsIdentity 类的静态 Impersonate 方法来实现。以下是MSDN 文档中对 Impersonate 方法的描述

使用零 userToken 值调用 Impersonate(IntPtr) 方法等效于调用 Win32 RevertToSelf 函数。如果当前正在模拟另一个用户,则控制权将恢复到原始用户。

用法如下所示:

using (var impersonationContext = WindowsIdentity.Impersonate(IntPtr.Zero))
{
    try
    {
        // this code is now using the application pool indentity
    }
    finally
    {
        if (impersonationContext != null)
        {
            impersonationContext.Undo();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)