模拟ASP.NET声明身份到Windows身份

Jaa*_*aap 5 .net asp.net impersonation wif

我有一个ASP.NET application使用基于ADFS的声明基础认证.我还WindowsClaimsIdentity使用Claims to Windows Identity Service 将其映射到a .这很好.

但现在我需要模拟当前的请求/线程,以便我可以访问不是声明感知的服务.我该怎么办?

我应该WindowsImpersonationContextApplication_PostAuthenticate事件中获得一个并将其保存在HttpContext.Items然后在Application_EndRequest调用Undo方法中吗?

或者还有其他首选方式吗?

更新:因为我没有得到任何关于模仿的首选方式的提示我尝试了自己的建议.我在global.asax.cs中创建了这段代码:

    private static readonly string WICKey = typeof(System.Security.Principal.WindowsImpersonationContext).AssemblyQualifiedName;

    protected void Application_PostAuthenticateRequest()
    {
        var wid = User.Identity as System.Security.Principal.WindowsIdentity;
        if (wid != null)
        {
            HttpContext.Current.Trace.Write("PostAuthenticateRequest PreImpersonate: " + System.Security.Principal.WindowsIdentity.GetCurrent().Name);
            HttpContext.Current.Items[WICKey] = wid.Impersonate();
            HttpContext.Current.Trace.Write("PostAuthenticateRequest PostImpersonate: " + System.Security.Principal.WindowsIdentity.GetCurrent().Name);
        }
    }

    protected void Application_EndRequest()
    {
        var wic = HttpContext.Current.Items[WICKey] as System.Security.Principal.WindowsImpersonationContext;
        if (wic != null)
        {
            HttpContext.Current.Trace.Write("EndRequest PreUndoImpersonate: " + System.Security.Principal.WindowsIdentity.GetCurrent().Name);
            wic.Undo();
            HttpContext.Current.Trace.Write("EndRequest PostUndoImpersonate: " + System.Security.Principal.WindowsIdentity.GetCurrent().Name);
        }
    }
Run Code Online (Sandbox Code Playgroud)

当我查看跟踪日志时,我看到了这一点

PostAuthenticateRequest PreImpersonate: NT AUTHORITY\NETWORK SERVICE   
PostAuthenticateRequest PostImpersonate: MyDomain\CorrectUser
Home: NT AUTHORITY\NETWORK SERVICE
EndRequest PreUndoImpersonate: NT AUTHORITY\NETWORK SERVICE
EndRequest PostUndoImpersonate: NT AUTHORITY\NETWORK SERVICE 
Run Code Online (Sandbox Code Playgroud)

因此,在第二行中,您可以看到线程被正确模拟.但是在下一行中你会看到模仿已经丢失.(第三行来自控制器).

当我使用以下代码在本地模拟时,它工作正常:

        var wid = User.Identity as System.Security.Principal.WindowsIdentity;
        if (wid != null)
        {
            using (var ctx = wid.Impersonate())
            {
                //Do something
            }
        }
Run Code Online (Sandbox Code Playgroud)

但我想模仿整个请求的生命周期.我该怎么办?

Ray*_*lli 1

您说后端服务不支持索赔。您能详细说明一下吗?您的意思是编译后的代码不支持声明,但您可以修改 web.config 文件吗?如果是这样,那么您可以尝试将后端服务配置为使用 WIF 管道进行 authN,方法是嵌入 WSFederationAuthenticationModule、SessionAuthenticationModule 和自定义 ClaimsAuthorizationManager(如果您还需要执行 authZ)。然后,当 ASP.NET 应用程序调用后端服务时,您可以使用 WIF 的 ActAs 或 OnBehalfOf 功能。