2012-02-02 9 views
5

Ho un ASP.NET application che utilizza l'autenticazione basata sulle attestazioni contro ADFS. Lo mappo anche a WindowsClaimsIdentity utilizzando le attestazioni su Windows Identity Service. Funziona beneImpersonare ASP.NET rivendica l'identità sull'identità Windows

Ma ora ho bisogno di impersonare la richiesta/thread corrente in modo da poter accedere a un servizio che non è consapevole delle richieste. Come dovrei farlo?

Devo acquisito una WindowsImpersonationContext in caso Application_PostAuthenticate e salvare che nel HttpContext.Items e poi nel Application_EndRequest chiamata al metodo Undo?

Oppure ci sono altri modi per farlo?

Aggiornamento: Poiché non ho trovato alcun indizio su quale sia il modo preferito di impersonare, ho provato il mio suggerimento. Ho creato questo codice nei 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); 
     } 
    } 

Quando guardo al registro di traccia vedo questo

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 

Così nella seconda riga si può vedere il filo viene rappresentato in modo corretto. Ma nelle prossime righe vedi che la rappresentazione è andata perduta. (la terza riga proviene da un controller).

Quando uso il seguente codice di impersonare localmente funziona benissimo:

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

ma voglio rappresentare l'intera richiesta vita. Come dovrei farlo?

risposta

1

Hai detto che il servizio di back-end non è a conoscenza delle richieste. Puoi approfondire questo? Intendi dire che il codice compilato non è a conoscenza delle attestazioni ma hai la possibilità di modificare il file web.config? In tal caso, provare a configurare il servizio di backend per utilizzare la pipeline WIF per authN tramite wedging in WSFederationAuthenticationModule, SessionAuthenticationModule e un ClaimsAuthorizationManager personalizzato se è necessario eseguire anche authZ. È quindi possibile utilizzare le funzioni ActAs o OnBehalfOf di WIF quando l'applicazione ASP.NET chiama il servizio di backend.

+0

Il servizio di back-end utilizza l'autenticazione di Windows e non posso modificare nulla nella sua configurazione. Oltre a ciò, sposterebbe solo il problema, perché quel servizio di backend sta accedendo a SQL Server con l'autenticazione di Windows impersonata. Quindi dovrei risolvere il mio problema lì. – Jaap

+0

Che dire di qualcosa come [questo] (http://www.syfuhs.net/post/2010/09/09/Converting-Claims-to-Windows-Tokens-and-User-Impersonation.aspx)? L'app ASP.NET può impersonare WindowsPrincipal per determinati blocchi di codice in cui chiama il servizio di backend. –

+0

Voglio impersonare nell'evento PostAuthenticateRequest in modo che l'intera richiesta possa essere eseguita in tale contesto rappresentato. Dopo aver impersonato la chiamata in PostAuthenticationRequest WindowsIdentity.GetCurrent(). Name restituisce effettivamente il nome utente previsto. Ma nel mio controller e successivamente in EndRequest ha di nuovo l'account NetworkService. E non fatto un impersonatingcontext.Undo()! – Jaap

-1

Ci scusiamo per la ricerca di questa vecchia discussione, ma affinché il codice funzioni, assicurati che la Modalità pipeline gestita del pool di applicazioni che esegue l'applicazione sia impostata su Classic.