2012-01-24 9 views
7

Ho un'app ASP.NET che richiede agli utenti di accedere con i loro account di dominio utilizzando l'autenticazione di base. L'utente può effettuare una selezione, quindi premere un pulsante.WindowsIdentity.Impersonate in ASP.NET in modo casuale "Token non valido per la rappresentazione - non può essere duplicato"

Ad un certo punto dopo aver premuto il pulsante è presente questo codice: WindowsIdentity.Impersonate(userIdentity.Token). userIdentity è di tipo WindowsIdentity ed è stato precedentemente impostato su (WindowsIdentity) User.Identity.

userIdentity viene memorizzato come variabile di sessione, e penso che sia perché, dopo aver premuto il pulsante, la pagina contenente questo codice viene chiamata tramite AJAX.

Quando si preme questo codice, funziona circa 2/3 del tempo, ma 1/3 del tempo, ottengo questa eccezione: Token non valido per la rappresentazione - non può essere duplicato. Penso che il più grande scratcher per me sia il motivo per cui funziona a volte ma non in altre occasioni? In alcune sessioni, funziona diverse volte prima di fallire. Sugli altri, fallisce subito.

Ecco la traccia dello stack:

a System.Security.Principal.WindowsIdentity.CreateFromToken (IntPtr userToken)

a System.Security.Principal.WindowsIdentity..ctor (IntPtr userToken, String AuthType , Int32 isAuthenticated)

a System.Security.Principal.WindowsIdentity.Impersonate (IntPtr userToken)

a Resource_Booker.BLL.ReservationAgent.Submit ReservationRequest (prenotazione, patron patron) in C: \ dev \ RoomRes \ Resource Booker \ BLL \ ReservationAgent.cs: riga 101

a Resource_Booker.Reserve.reserve_Click (oggetto mittente, EventArgs e) in C: \ dev \ RoomRes \ Resource Booker \ Reserve.aspx.cs: linea 474

a System.EventHandler.Invoke (Object sender, EventArgs e)

a System.Web.UI.WebControls.Button.RaisePostBackEvent (String eventArgument)

a System.Web.UI.Page.ProcessRequestMain (Booleano includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Ecco un fattore di confusione: non riesco a riprodurre questo problema sulla mia workstation Windows 7 x64 locale - anche se la mia autenticazione viene passato implicitamente qui da quando sto usando localhost - o su un Windows 2003 a 32 bit di IIS 6.0 ambiente . Succede solo su un ambiente Windows 2008 R2 piuttosto vanilla. Tutti questi ambienti sono membri del dominio.

+0

Questo problema potrebbe spaventarmi perché sembra che un handle non valido sia stato utilizzato internamente da .NET Framework. Questo è potenzialmente critico per la sicurezza. – usr

risposta

8

In sostanza ciò che si vede non è un problema di sicurezza poiché la sessione di accesso viene memorizzata nella cache da IIS per la durata della connessione TCP, ma HTTP occasionalmente interromperà la connessione TCP che richiede la ri-autenticazione. Ciò avverrà in modo trasparente e invisibile (gestito dal browser) ma invaliderà il token, poiché la sessione di accesso verrà distrutta al termine della connessione TCP.

I.e.a vantaggio di @usr, funziona solo a volte perché la sessione di accesso è la stessa così il token è lo stesso, quindi il token memorizzato nella sessione funziona perché è lo stesso token effettivo di User.Identity. Non è un modo per evitare il controllo di sicurezza, si tratta di un dettaglio di implementazione del controllo di sicurezza.

Non archiviare l'identità nella sessione: non è necessario poiché si tratta di una connessione autenticata.

Basta usare (WindowsIdentity)User.Identity ogni volta e il problema dovrebbe andare via.

+1

Questo sembra essere il problema. Per una soluzione rapida, ho trovato dove ** userIdentity ** veniva estratto dalla variabile di sessione e forzato il programma a riattivarlo. Grazie! –

+0

@ Ben: Grazie per l'ottima spiegazione. Mi chiedo se (WindowsIdentity) User.Identity funzionerà con l'autenticazione di Windows e manyToOneCertificateMapping abilitato? Io non la penso così, sfortunatamente non posso testare questo adesso. – Kr15

+0

@ Kr15, Se l'utente è stato autenticato correttamente con l'autenticazione di Windows, allora '(WindowsIdentity) User.Identity' funzionerà. – Ben

Problemi correlati