Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
In questo argomento viene descritto come un'applicazione ASP.NET possa utilizzare l'autenticazione basata su form per consentire agli utenti di eseguire l'autenticazione a Servizi di dominio Active Directory utilizzando il protocollo LDAP (Lightweight Directory Access Protocol). Dopo l'autenticazione e il reindirizzamento dell'utente, è possibile utilizzare il metodo Application_AuthenticateRequest del file Global.asax per memorizzare un oggetto GenericPrincipal nella proprietà HttpContext.User presente nell'intera richiesta.
Per creare una nuova applicazione Web ASP.NET
Avviare Microsoft Visual Studio .NET.
Scegliere Nuovo dal menu File, quindi fare clic su Progetto.
Fare clic su Progetti Visual C# in Tipi progetto, quindi fare clic su Applicazione Web ASP.NET in Modelli.
Nella casella Nome digitare FormsAuthAd.
Lasciare il valore predefinito https://localhost nella casella Server se si utilizza il server locale. Altrimenti aggiungere il percorso del server in uso. Scegliere OK.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo Riferimenti e scegliere Aggiungi riferimento.
Nella scheda .NET della finestra di dialogo Aggiungi riferimento fare clic su System.DirectoryServices.dll, scegliere Seleziona, quindi fare clic su OK.
Per aggiungere il codice di autenticazione di System.DirectoryServices
In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo del progetto, scegliere Aggiungi, quindi fare clic su Aggiungi nuovo elemento.
In Modelli fare clic su Classe.
Digitare LdapAuthentication.cs nella casella Nome, quindi scegliere Apri.
Sostituire il codice esistente nel file LdapAuthentication.cs con il codice seguente:
using System; using System.Text; using System.Collections; using System.Web.Security; using System.Security.Principal; using System.DirectoryServices; namespace FormsAuth { public class LdapAuthentication { private string _path; private string _filterAttribute; public LdapAuthentication(string path) { _path = path; } public bool IsAuthenticated(string domain, string username, string pwd) { string domainAndUsername = domain + @"\" + username; DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd); try { //Bind to the native AdsObject to force authentication. object obj = entry.NativeObject; DirectorySearcher search = new DirectorySearcher(entry); search.Filter = "(SAMAccountName=" + username + ")"; search.PropertiesToLoad.Add("cn"); SearchResult result = search.FindOne(); if(null == result) { return false; } //Update the new path to the user in the directory. _path = result.Path; _filterAttribute = (string)result.Properties["cn"][0]; } catch (Exception ex) { throw new Exception("Error authenticating user. " + ex.Message); } return true; } public string GetGroups() { DirectorySearcher search = new DirectorySearcher(_path); search.Filter = "(cn=" + _filterAttribute + ")"; search.PropertiesToLoad.Add("memberOf"); StringBuilder groupNames = new StringBuilder(); try { SearchResult result = search.FindOne(); int propertyCount = result.Properties["memberOf"].Count; string dn; int equalsIndex, commaIndex; for(int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++) { dn = (string)result.Properties["memberOf"][propertyCounter]; equalsIndex = dn.IndexOf("=", 1); commaIndex = dn.IndexOf(",", 1); if(-1 == equalsIndex) { return null; } groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1)); groupNames.Append("|"); } } catch(Exception ex) { throw new Exception("Error obtaining group names. " + ex.Message); } return groupNames.ToString(); } } }
Nella procedura precedente il codice di autenticazione accetta un dominio, un nome utente, una password e il percorso dell'albero in Servizi di dominio Active Directory. Questo codice utilizza il provider di directory LDAP. Il codice nella pagina Logon.aspx chiama il metodo LdapAuthentication.IsAuthenticated e passa le credenziali raccolte dall'utente. Quindi viene creato un oggetto DirectoryEntry con il percorso dell'albero della directory, il nome utente e la password. Il nome utente deve essere nel formato dominio\nomeutente.
L'oggetto DirectoryEntry cerca quindi di imporre il collegamento di AdsObject ottenendo la proprietà NativeObject. Se l'operazione riesce, l'attributo CN dell'utente viene ottenuto mediante la creazione di un oggetto DirectorySearcher e il filtro di sAMAccountName. Per ulteriori informazioni sAMAccountName nello schema di Servizi di dominio Active Directory, vedere "sAMAccountName" o "Attributo SAM-Account-Name" in MSDN Library (le informazioni potrebbero essere in lingua inglese). Dopo l'autenticazione dell'utente, il metodo IsAuthenticated restituisce true. Per ottenere l'elenco dei gruppi a cui l'utente appartiene, viene chiamato il metodo LdapAuthentication.GetGroups, il quale ottiene l'elenco dei gruppi di protezione e distribuzione a cui l'utente appartiene creando un oggetto DirectorySearcher e filtrando in base all'attributo memberOf. Per ulteriori informazioni memberOf nello schema di Servizi di dominio Active Directory, vedere "memberOf" o "Attributo Is-Member-Of-DL" in MSDN Library (le informazioni potrebbero essere in lingua inglese). Questo metodo restituisce l'elenco dei gruppi separati da barre verticali (|). Si noti che il metodo LdapAuthentication.GetGroups modifica e tronca le stringhe, riducendo in tal modo la lunghezza della stringa memorizzata nel cookie di autenticazione. Se la stringa non è troncata, il formato di ciascun gruppo è il seguente:
CN=...,...,DC=domain,DC=com
Il metodo LdapAuthentication.GetGroups può restituire una stringa molto lunga. Se la lunghezza di tale stringa è maggiore di quella del cookie, non è possibile creare il cookie di autenticazione. Se la stringa dovesse eccedere la lunghezza del cookie, è opportuno memorizzare le informazioni sui gruppi nell'oggetto cache ASP.NET o in un database. In alternativa è possibile crittografare le informazioni sui gruppi e memorizzarle in un campo di form nascosto.
Il codice nel file Global.asax rende disponibile un gestore eventi Application_AuthenticateRequest che recupera il cookie di autenticazione dall'insieme Context.Request.Cookies, decrittografa il cookie e recupera l'elenco dei gruppi che verrà memorizzato nella proprietà FormsAuthenticationTicket.UserData. I gruppi compaiono in un elenco creato nella pagina Logon.aspx e separati da barre verticali. Il codice analizza la stringa in una matrice di stringe per creare un oggetto GenericPrincipal. Dopo la creazione, l'oggetto GenericPrincipal viene collocato nella proprietà HttpContext.User.
Per scrivere il codice di Global.asax
In Esplora soluzioni fare clic con il pulsante destro del mouse su Global.asax, quindi scegliere Visualizza codice.
Aggiungere il codice seguente all'inizio del code-behind per il file Global.asax.cs:
using System.Web.Security; using System.Security.Principal;Sostituire il gestore eventi vuoto esistente per Application_AuthenticateRequest con il codice seguente:
void Application_AuthenticateRequest(object sender, EventArgs e) { string cookieName = FormsAuthentication.FormsCookieName; HttpCookie authCookie = Context.Request.Cookies[cookieName]; if(null == authCookie) { //There is no authentication cookie. return; } FormsAuthenticationTicket authTicket = null; try { authTicket = FormsAuthentication.Decrypt(authCookie.Value); } catch(Exception ex) { //Write the exception to the Event Log. return; } if(null == authTicket) { //Cookie failed to decrypt. return; } //When the ticket was created, the UserData property was assigned a //pipe-delimited string of group names. string[] groups = authTicket.UserData.Split(new char[]{'|'}); //Create an Identity. GenericIdentity id = new GenericIdentity(authTicket.Name, "LdapAuthentication"); //This principal flows throughout the request. GenericPrincipal principal = new GenericPrincipal(id, groups); Context.User = principal; }
In questa sezione vengono configurati gli elementi <form>, <authentication> e <authorization> del file Web.config. Con tali modifiche, solo gli utenti autenticati possono accedere all'applicazione, mentre le richieste non autenticate vengono reindirizzate a una pagina Logon.aspx. È possibile modificare questa configurazione per consentire solo a determinati utenti e gruppi di accedere all'applicazione.
Per modificare il file Web.config
Aprire Web.config in Blocco note.
Sostituire il codice esistente con il seguente:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <authentication mode="Forms"> <forms loginUrl="logon.aspx" name="adAuthCookie" timeout="10" path="/"> </forms> </authentication> <authorization> <deny users="?"/> <allow users="*"/> </authorization> <identity impersonate="true"/> </system.web> </configuration>
Si noti il seguente elemento di configurazione:
<identity impersonate="true"/>
Questo elemento fa sì che ASP.NET rappresenti l'account configurato come quello anonimo di Microsoft Internet Information Services (IIS). In conseguenza di questa configurazione, tutte le richieste all'applicazione vengono eseguite nel contesto di protezione dell'account configurato. L'utente fornisce le credenziali per eseguire l'autenticazione a Servizi di dominio Active Directory, ma l'account che accede a Servizi di dominio Active Directory è l'account configurato.
Per configurare IIS per l'autenticazione anonima
In Gestione IIS (in Strumenti di amministrazione) o nello snap-in di MMC per IIS fare clic con il pulsante destro del mouse sul sito Web per il quale si desidera configurare l'autenticazione, quindi scegliere Proprietà.
Fare clic sull scheda Protezione directory, quindi scegliere Modifica in Controllo autenticazione e accesso.
Selezionare la casella di controllo Autenticazione anonima (Abilita accesso anonimo in Windows Server 2003).
Fare dell'account anonimo per l'applicazione l'account dotato delle autorizzazioni per Servizi di dominio Active Directory.
Deselezionare la casella di controllo Abilita controllo delle password, se presente. L'account IUSR*_<nomecomputer>* predefinito non ha le autorizzazioni per Servizi di dominio Active Directory.
Per creare la pagina Logon.aspx
In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo del progetto, scegliere Aggiungi, quindi fare clic su Aggiungi Web Form.
Digitare Logon.aspx nella casella Nome, quindi scegliere Apri.
In Esplora soluzioni fare clic con il pulsante destro del mouse su Logon.aspx, quindi scegliere Progettazione viste.
Selezionare la scheda HTML in Finestra di progettazione.
Sostituire il codice esistente con il seguente:
<%@ Page language="c#" AutoEventWireup="true" %> <%@ Import Namespace="FormsAuth" %> <html> <body> <form id="Login" method="post" > <asp:Label ID="Label1" Runat=server >Domain:</asp:Label> <asp:TextBox ID="txtDomain" Runat=server ></asp:TextBox><br> <asp:Label ID="Label2" Runat=server >Username:</asp:Label> <asp:TextBox ID=txtUsername Runat=server ></asp:TextBox><br> <asp:Label ID="Label3" Runat=server >Password:</asp:Label> <asp:TextBox ID="txtPassword" Runat=server TextMode=Password></asp:TextBox><br> <asp:Button ID="btnLogin" Runat=server Text="Login" OnClick="Login_Click"></asp:Button><br> <asp:Label ID="errorLabel" Runat=server ForeColor=#ff3300></asp:Label><br> <asp:CheckBox ID=chkPersist Runat=server Text="Persist Cookie" /> </form> </body> </html> <script runat=server> void Login_Click(object sender, EventArgs e) { string adPath = "LDAP://" + txtDomain.Text; LdapAuthentication adAuth = new LdapAuthentication(adPath); try { if(true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text)) { string groups = adAuth.GetGroups(txtDomain.Text, txtUsername.Text, txtPassword.Text); //Create the ticket, and add the groups. bool isCookiePersistent = chkPersist.Checked; FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, txtUsername.Text,DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups); //Encrypt the ticket. string encryptedTicket = FormsAuthentication.Encrypt(authTicket); //Create a cookie, and then add the encrypted ticket to the cookie as data. HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); if(true == isCookiePersistent) authCookie.Expires = authTicket.Expiration; //Add the cookie to the outgoing cookies collection. Response.Cookies.Add(authCookie); //You can redirect now. Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false)); } else { errorLabel.Text = "Authentication did not succeed. Check user name and password."; } } catch(Exception ex) { errorLabel.Text = "Error authenticating. " + ex.Message; } } </script>Modificare il percorso nella pagina Logon.aspx in modo che faccia riferimento al server di directory LDAP in uso.
La pagina Logon.aspx raccoglie le informazioni dall'utente e chiama i metodi della classe LdapAuthentication. Dopo avere autenticato l'utente e ottenuto l'elenco dei gruppi, il codice crea un oggetto FormsAuthenticationTicket, crittografa il ticket, aggiunge il ticket crittografato a un cookie, aggiunge il cookie all'insieme HttpResponse.Cookies e reindirizza la richiesta all'URL originariamente richiesto.
La pagina WebForm1.aspx è quella richiesta originariamente. Quando l'utente richiede questa pagina, la richiesta viene reindirizzata alla pagina Logon.aspx. Dopo essere stata autenticata, la richiesta viene reindirizzata alla pagina WebForm1.aspx.
Per modificare la pagina WebForm1.aspx
In Esplora soluzioni fare clic con il pulsante destro del mouse su WebForm1.aspx, quindi scegliere Progettazione viste.
Selezionare la scheda HTML in Finestra di progettazione.
Sostituire il codice esistente con il seguente:
<%@ Page language="c#" AutoEventWireup="true" %> <%@ Import Namespace="System.Security.Principal" %> <html> <body> <form id="Form1" method="post" > <asp:Label ID="lblName" Runat=server /><br> <asp:Label ID="lblAuthType" Runat=server /> </form> </body> </html> <script runat=server> void Page_Load(object sender, EventArgs e) { lblName.Text = "Hello " + Context.User.Identity.Name + "."; lblAuthType.Text = "You were authenticated using " + Context.User.Identity.AuthenticationType + "."; } </script>Salvare tutti i file, quindi compilare il progetto.
Richiedere la pagina WebForm1.aspx. Si noti che si viene reindirizzati alla pagina Logon.aspx.
Digitare le credenziali di accesso, quindi scegliere Invia. Quando si viene reindirizzati a WebForm1.aspx, si osservi la comparsa del nome utente e si noti che LdapAuthentication è il tipo di autenticazione per la proprietà Context.User.AuthenticationType.
Nota: |
|---|
| È consigliabile utilizzare la crittografia SSL (Secure Sockets Layer) quando si utilizza l'autenticazione basata su form perché l'utente viene identificato in base al cookie di identificazione e la crittografia SSL dell'applicazione impedisce a chiunque di compromettere il cookie di autenticazione e qualsiasi altra informazione preziosa che viene trasmessa. |
Vedere anche
Riferimenti
System.DirectoryServices
DirectoryEntry
DirectorySearcher
Concetti
Argomenti di programmazione avanzata
Send comments about this topic to Microsoft.
Copyright © 2007 Microsoft Corporation. Tutti i diritti riservati.
Nota: