2012-02-02 18 views
5

我有一个ASP.NET application它使用针对ADFS的声明基础身份验证。我还通过使用对Windows身份识别服务的声明将其映射到WindowsClaimsIdentity。这工作正常。冒充ASP.NET声称身份到Windows身份

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

我应该在Application_PostAuthenticate事件获得了WindowsImpersonationContext并保存在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); 
     } 
    } 

当我看向跟踪日志我看到这个

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 
      } 
     } 

但我想冒充整个请求寿命。 我该怎么做?

回答

1

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

+0

后端服务正在使用Windows身份验证,我无法更改任何配置。除此之外,它只会解决问题,因为后端服务正在使用Windows身份验证访问SQL-Server。那么我必须在那里解决我的问题。 – Jaap 2012-02-03 07:31:42

+0

[this](http://www.syfuhs.net/post/2010/09/09/Converting-Claims-to-Windows-Tokens-and-User-Impersonation.aspx)呢?您的ASP.NET应用程序可以为它调用后端服务的某些代码块模拟WindowsPrincipal。 – 2012-02-03 14:19:38

+0

我想模拟PostAuthenticateRequest事件,以便整个请求可以在该模拟的上下文中运行。在PostAuthenticationRequest中模拟呼叫后,WindowsIdentity.GetCurrent()。名称返回确实是预期的用户名。但在我的控制器中,然后在EndRequest中它又有了NetworkService帐户。并没有做一个模拟的文字。撤消()! – Jaap 2012-02-15 11:16:24

-1

对不起,要挖掘这个旧线程,但为了您的代码正常工作,请确保运行您的应用程序的应用程序池的管理管道模式设置为经典