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

时间:2012-02-02 21:32:30

标签: asp.net .net impersonation wif

我有一个ASP.NET application,它使用针对ADFS的声明基础身份验证。我还使用声明到Windows身份服务将其映射到WindowsClaimsIdentity。这很好。

但是现在我需要模拟当前的请求/线程,以便我可以访问一个不能声明的服务。我该怎么做?

我是否应该在WindowsImpersonationContext事件中获得Application_PostAuthenticate并将其保存在HttpContext.Items中,然后在Application_EndRequest中调用撤消方法?

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

更新:由于我没有得到任何关于冒充首选方法的提示,我尝试了自己的建议。我在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);
        }
    }

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

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 

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

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

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

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

2 个答案:

答案 0 :(得分:1)

您说后端服务不是声明。你能详细说明一下吗?你的意思是编译的代码不是声明的,但你有能力修改web.config文件?如果是这样,那么您可以尝试配置后端服务以通过在WSFederationAuthenticationModule,SessionAuthenticationModule和自定义ClaimsAuthorizationManager中使用WIF管道来进行authN,如果您还需要执行authZ。然后,当ASP.NET应用程序调用后端服务时,您可以使用WIF的ActAs或OnBehalfOf功能。

答案 1 :(得分:-1)

很抱歉挖掘这个旧线程,但为了让您的代码正常工作,请确保运行您的应用程序的应用程序池的托管管道模式设置为经典