Impersonare utilizzando l’autenticazione basata su moduli

Dispongo di un sito ASP.NET che deve utilizzare Autenticazione moduli e non Autenticazione Windows per accedere a ActiveDirectoryMembershipProvider . Il sito deve utilizzare i moduli perché richiedono un modulo di input progettato anziché il popup di autenticazione del browser utilizzato dall’autenticazione di Windows.

Il sito deve impersonare l’utente che ha effettuato l’accesso tramite Active Directory per accedere a file specifici dell’utente.

Tuttavia, WindowsIdentity.GetCurrent() non è lo stesso di HttpContext.Current.User.Identity sebbene il mio web.config contenga:

     

Non riesco a utilizzare LoginUser() e WindowsIdentity.Impersonate() perché devo impersonare l’utente AD per ottenere le autorizzazioni specifiche e non conosco la password dell’utente perché Forms si occupa dell’accesso.

È ansible forse dal login.aspx.cs, prendere System.Web.UI.WebControls.Login.Password , quindi salvare il token LoginUser() in una variabile di sessione per WindowsIdentity.Impersonate() più tardi? O forse un metodo molto più sicuro di impersonare nel modo giusto?

Sono confuso perché l’autenticazione basata su form non può automaticamente

Ho letto questo http://msdn.microsoft.com/en-us/library/ms998351.aspx ma utilizza l’autenticazione di Windows.

La rappresentazione di un utente tramite l’autenticazione basata su moduli può essere eseguita. Il seguente codice funziona .

L’ articolo di Visual Studio Magazine a cui fa riferimento Robert è una risorsa eccellente. Ci sono alcuni problemi con il codice di esempio nell’articolo, quindi ho incluso del codice funzionante di seguito.

Nota: se si utilizza Visual Studio, assicurarsi di avviarlo ” Esegui come amministratore ” per evitare problemi con la rappresentazione del blocco del controllo dell’account utente.

 // in your login page (hook up to OnAuthenticate event) protected void LoginControl_Authenticate(object sender, AuthenticateEventArgs e) { int token; // replace "YOURDOMAIN" with your actual domain name e.Authenticated = LogonUser(LoginUser.UserName,"YOURDOMAIN",LoginUser.Password,8,0,out token); if (e.Authenticated) { Session.Add("principal", new WindowsPrincipal(new WindowsIdentity(new IntPtr(token)))); } } [DllImport("advapi32.dll", SetLastError = true)] public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out int TokenHandle); // in global.asax.cs void Application_PreRequestHandlerExecute(object send, EventArgs e) { if (Thread.CurrentPrincipal.Identity.IsAuthenticated == true && HttpContext.Current.Session != null) { WindowsPrincipal windowsPrincipal = (WindowsPrincipal)Session["principal"]; Session["principal"] = (GenericPrincipal)Thread.CurrentPrincipal; Thread.CurrentPrincipal = windowsPrincipal; HttpContext.Current.User = windowsPrincipal; HttpContext.Current.Items["identity"] = ((WindowsIdentity)windowsPrincipal.Identity).Impersonate(); } } // in global.asax.cs void Application_PostRequestHandlerExecute(object send, EventArgs e) { if (HttpContext.Current.Session != null && Session["principal"] as GenericPrincipal != null) { GenericPrincipal genericPrincipal = (GenericPrincipal)Session["principal"]; Session["principal"] = (WindowsPrincipal)Thread.CurrentPrincipal; Thread.CurrentPrincipal = genericPrincipal; HttpContext.Current.User = genericPrincipal; ((WindowsImpersonationContext)HttpContext.Current.Items["identity"]).Undo(); } } // test that impersonation is working (add this and an Asp:Label to a test page) protected void Page_Load(object sender, EventArgs e) { try { // replace YOURSERVER and YOURDB with your actual server and database names string connstring = "data source=YOURSERVER;initial catalog=YOURDB;integrated security=True"; using (SqlConnection conn = new SqlConnection(connstring)) { conn.Open(); SqlCommand cmd = new SqlCommand("SELECT SUSER_NAME()", conn); using (SqlDataReader rdr = cmd.ExecuteReader()) { rdr.Read(); Label1.Text = "SUSER_NAME() = " + rdr.GetString(0); } } } catch { } } 

Aggiornare:

Dovresti anche gestire Application_EndRequest , perché chiamate come Response.End() ignoreranno Application_PostRequestHandlerExecute .

Un altro problema è che WindowsIdentity può ottenere la raccolta dei dati inutili, pertanto è necessario creare un nuovo WindowsIdentity e WindowsPrincipal dal token di accesso su ogni richiesta.

Update2:

Non sono sicuro del motivo per cui questo è stato downvoted, perché funziona. Ho aggiunto la firma pinvoke e un codice di prova. Ancora una volta, avviare Visual Studio utilizzando ” Esegui come amministratore “. Google come farlo se non sai come.

Se i tuoi utenti utilizzano IE, puoi triggersre la sicurezza integrata per il sito Web e gli utenti verranno autenticati automaticamente (nessuna finestra di accesso, nessuna pagina di accesso). La tua imitazione funzionerà quindi. Se devi scegliere come target altri browser, questo potrebbe non funzionare (probabilmente all’utente verrà presentata una finestra di accesso).

La tua attuale impersonificazione non funzionerà mai perché i tuoi utenti effettuano l’accesso utilizzando un account diverso dal proprio account di dominio. Non puoi pretendere che il sito impersonifichi un utente che non ha fornito le sue credenziali. Ciò andrebbe contro i principi di sicurezza di base.

Potresti trovare utile questo:

  • come creare una schermata di accesso che consenta agli utenti Admin di accedere come un altro utente nel database degli utenti

MODIFICARE

Leggendo la tua domanda più da vicino, non sono sicuro che questo approccio funzionerebbe comunque con il tuo scenario; quando effettui l’accesso utilizzando l’autenticazione basata su form e impersonare l’utente di Active Directory

Abbiamo avuto lo stesso problema di recente, il cliente voleva che gli utenti potessero accedere tramite l’account AD e quindi questa credenziale deve essere utilizzata per accedere a Analysis Service e tutti gli altri database. Lo hanno voluto in questo modo perché hanno implementato un sistema di auditing e tutti gli accessi devono essere effettuati dall’account loggato corrente.

Abbiamo provato l’autenticazione basata su form e l’API Win32 LogonUser () per impersonare la parte, ha funzionato ma ci chiede anche la password dell’utente come testo normale. In seguito, abbiamo deciso di utilizzare l’autenticazione di Windows, ci fa risparmiare molto tempo (non più autenticazione AD, impersonare manualmente). Naturalmente, non c’era nemmeno una pagina di accesso di fantasia.

Per caso, e un po ‘tardi, ho trovato qualcosa che funziona per me ed è molto semplice, ma ovviamente è solo a scopo di test …

Basta impostare un cookie con il tuo nome utente.

 //Login button. You can give whatever input to the form protected void Login_Click(object sender, EventArgs e) { FormsAuthentication.SetAuthCookie("your_username", createPersistentCookie: true); Response.Redirect("~/"); } 

Qualsiasi commento accettato …

In Visual Studio installa NuGet Apri la tua soluzione

Quindi nella console del pacchetto esegui Install-Package 51Degrees.mobi

Aggiungerà quindi 51 Gradi al tuo sito web. È quindi ansible modificare 51Degrees.mobi.config nei dati dell’app per rimuovere la sezione di reindirizzamento.

Ora avrai le funzionalità del browser aggiornate