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?
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
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. –
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