Implementare l'autenticazione basata su moduli in un'applicazione ASP.NET usando C#.NET
Questo articolo illustra come implementare l'autenticazione basata su moduli usando un database per archiviare gli utenti. Fa riferimento agli spazi dei nomi della libreria di classi microsoft .NET Framework seguenti:
System.Data.SqlClient
System.Web.Security
Versione originale del prodotto: ASP.NET
Numero KB originale: 301240
Requisiti
L'elenco seguente illustra i service pack consigliati per hardware, software, infrastruttura di rete e Service Pack necessari:
- Visual Studio .NET
- Internet Information Services (IIS) versione 5.0 o successiva
- SQL Server
Creare un'applicazione ASP.NET usando C# .NET
- Aprire Visual Studio .NET.
- Creare una nuova applicazione Web ASP.NET e specificare il nome e il percorso.
Configurare le impostazioni di sicurezza nel file Web.config
Questa sezione illustra come aggiungere e modificare le <authentication>
sezioni di configurazione e <authorization>
per configurare l'applicazione ASP.NET per l'uso dell'autenticazione basata su form.
In Esplora soluzioni aprire il file Web.config.
Modificare la modalità di autenticazione in Form.
Inserire il
<Forms>
tag e riempire gli attributi appropriati. Copiare il codice seguente e quindi selezionare Incolla come HTML dal menu Modifica per incollare il codice nella<authentication>
sezione del file:<authentication mode="Forms"> <forms name=".ASPXFORMSDEMO" loginUrl="logon.aspx" protection="All" path="/" timeout="30" /> </authentication>
Negare l'accesso all'utente anonimo nella
<authorization>
sezione come indicato di seguito:<authorization> <deny users ="?" /> <allow users = "*" /> </authorization>
Creare una tabella di database di esempio per archiviare i dettagli degli utenti
Questa sezione illustra come creare un database di esempio per archiviare il nome utente, la password e il ruolo per gli utenti. È necessaria la colonna ruolo se si vogliono archiviare i ruoli utente nel database e implementare la sicurezza basata sui ruoli.
Nel menu Start selezionare Esegui e quindi digitare Blocco note per aprire Blocco note.
Evidenziare il codice script SQL seguente, fare clic con il pulsante destro del mouse sul codice e quindi scegliere Copia. Nel Blocco note selezionare Incolla dal menu Modifica per incollare il codice seguente:
if exists (select * from sysobjects where id = object_id(N'[dbo].[Users]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[Users] GO CREATE TABLE [dbo].[Users] ([uname] [varchar] (15) NOT NULL, [Pwd] [varchar] (25) NOT NULL, [userRole] [varchar] (25) NOT NULL, ) ON [PRIMARY] GO ALTER TABLE [dbo].[Users] WITH NOCHECK ADD CONSTRAINT [PK_Users] PRIMARY KEY NONCLUSTERED ([uname] ) ON [PRIMARY] GO INSERT INTO Users values('user1','user1','Manager') INSERT INTO Users values('user2','user2','Admin') INSERT INTO Users values('user3','user3','User') GO
Salvare il file come Users.sql.
Nel computer SQL Server aprire Users.sql in Query Analyzer. Nell'elenco dei database selezionare pubs ed eseguire lo script. Questa operazione crea una tabella di utenti di esempio e popola la tabella nel database Pubs da usare con questa applicazione di esempio.
Creare una pagina di Logon.aspx
Aggiungere un nuovo Web Form al progetto denominato Logon.aspx.
Aprire la pagina Logon.aspx nell'editor e passare alla visualizzazione HTML.
Copiare il codice seguente e usare l'opzione Incolla come HTML nel menu Modifica per inserire il codice tra i
<form>
tag:<h3> <font face="Verdana">Logon Page</font> </h3> <table> <tr> <td>Email:</td> <td><input id="txtUserName" type="text" runat="server"></td> <td><ASP:RequiredFieldValidator ControlToValidate="txtUserName" Display="Static" ErrorMessage="*" runat="server" ID="vUserName" /></td> </tr> <tr> <td>Password:</td> <td><input id="txtUserPass" type="password" runat="server"></td> <td><ASP:RequiredFieldValidator ControlToValidate="txtUserPass" Display="Static" ErrorMessage="*" runat="server" ID="vUserPass" /> </td> </tr> <tr> <td>Persistent Cookie:</td> <td><ASP:CheckBox id="chkPersistCookie" runat="server" autopostback="false" /></td> <td></td> </tr> </table> <input type="submit" Value="Logon" runat="server" ID="cmdLogin"><p></p> <asp:Label id="lblMsg" ForeColor="red" Font-Name="Verdana" Font-Size="10" runat="server" />
Questo Modulo Web viene usato per presentare un modulo di accesso agli utenti in modo che possano specificare il nome utente e la password per accedere all'applicazione.
Per altre informazioni, vedere Classe RequiredFieldValidator.
Passare alla visualizzazione Progettazione e salvare la pagina.
Codificare il gestore eventi in modo da convalidare le credenziali utente
In questa sezione viene presentato il codice inserito nella pagina code-behind (Logon.aspx.cs).
Fare doppio clic su Accesso per aprire il file di Logon.aspx.cs .
Importare gli spazi dei nomi necessari nel file code-behind:
using System.Data.SqlClient; using System.Web.Security;
Creare una
ValidateUser
funzione per convalidare le credenziali utente cercando nel database. Assicurarsi di modificare laConnection
stringa in modo che punti al database.private bool ValidateUser( string userName, string passWord ) { SqlConnection conn; SqlCommand cmd; string lookupPassword = null; // Check for invalid userName. // userName must not be null and must be between 1 and 15 characters. if ( ( null == userName ) || ( 0 == userName.Length ) || ( userName.Length > 15 )) { System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of userName failed." ); return false; } // Check for invalid passWord. // passWord must not be null and must be between 1 and 25 characters. if ( ( null == passWord ) || ( 0 == passWord.Length ) || ( passWord.Length > 25 )) { System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of passWord failed." ); return false; } try { // Consult with your SQL Server administrator for an appropriate connection // string to use to connect to your local SQL Server. conn = new SqlConnection( "server=localhost;Integrated Security=SSPI;database=pubs" ); conn.Open(); // Create SqlCommand to select pwd field from users table given supplied userName. cmd = new SqlCommand( "Select pwd from users where uname=@userName", conn ); cmd.Parameters.Add( "@userName", SqlDbType.VarChar, 25 ); cmd.Parameters["@userName"].Value = userName; // Execute command and fetch pwd field into lookupPassword string. lookupPassword = (string) cmd.ExecuteScalar(); // Cleanup command and connection objects. cmd.Dispose(); conn.Dispose(); } catch ( Exception ex ) { // Add error handling here for debugging. // This error message should not be sent back to the caller. System.Diagnostics.Trace.WriteLine( "[ValidateUser] Exception " + ex.Message ); } // If no password found, return false. if ( null == lookupPassword ) { // You could write failed login attempts here to event log for additional security. return false; } // Compare lookupPassword and input passWord, using a case-sensitive comparison. return ( 0 == string.Compare( lookupPassword, passWord, false )); }
È possibile usare uno dei due metodi per generare il cookie di autenticazione basata su form e reindirizzare l'utente a una pagina appropriata nell'evento
cmdLogin_ServerClick
. Il codice di esempio viene fornito per entrambi gli scenari. Usarli in base alle esigenze.Chiamare il
RedirectFromLoginPage
metodo per generare automaticamente il cookie di autenticazione basata su form e reindirizzare l'utente a una pagina appropriata nell'eventocmdLogin_ServerClick
:private void cmdLogin_ServerClick(object sender, System.EventArgs e) { if (ValidateUser(txtUserName.Value,txtUserPass.Value)) FormsAuthentication.RedirectFromLoginPage(txtUserName.Value, chkPersistCookie.Checked); else Response.Redirect("logon.aspx", true); }
Generare il ticket di autenticazione, crittografarlo, creare un cookie, aggiungerlo alla risposta e reindirizzare l'utente. Questa operazione offre un maggiore controllo sulla creazione del cookie. È anche possibile includere dati personalizzati insieme a
FormsAuthenticationTicket
in questo caso.private void cmdLogin_ServerClick(object sender, System.EventArgs e) { if (ValidateUser(txtUserName.Value,txtUserPass.Value)) { FormsAuthenticationTicket tkt; string cookiestr; HttpCookie ck; tkt = new FormsAuthenticationTicket(1, txtUserName.Value, DateTime.Now, DateTime.Now.AddMinutes(30), chkPersistCookie.Checked, "your custom data"); cookiestr = FormsAuthentication.Encrypt(tkt); ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr); if (chkPersistCookie.Checked) ck.Expires=tkt.Expiration; ck.Path = FormsAuthentication.FormsCookiePath; Response.Cookies.Add(ck); string strRedirect; strRedirect = Request["ReturnUrl"]; if (strRedirect==null) strRedirect = "default.aspx"; Response.Redirect(strRedirect, true); } else Response.Redirect("logon.aspx", true); }
Assicurarsi che il codice seguente venga aggiunto al
InitializeComponent
metodo nel codice generato da Progettazione Web Form:this.cmdLogin.ServerClick += new System.EventHandler(this.cmdLogin_ServerClick);
Creare una pagina di Default.aspx
Questa sezione crea una pagina di test a cui gli utenti vengono reindirizzati dopo l'autenticazione. Se gli utenti passano a questa pagina senza prima accedere all'applicazione, vengono reindirizzati alla pagina di accesso.
Rinominare la pagina WebForm1.aspx esistente come Default.aspx e aprirla nell'editor.
Passare alla visualizzazione HTML e copiare il codice seguente tra i
<form>
tag:<input type="submit" Value="SignOut" runat="server" id="cmdSignOut">
Questo pulsante viene usato per disconnettersi dalla sessione di autenticazione basata su form.
Passare alla visualizzazione Progettazione e salvare la pagina.
Importare gli spazi dei nomi necessari nel file code-behind:
using System.Web.Security;
Fare doppio clic su SignOut per aprire la pagina code-behind (Default.aspx.cs) e copiare il codice seguente nel
cmdSignOut_ServerClick
gestore eventi:private void cmdSignOut_ServerClick(object sender, System.EventArgs e) { FormsAuthentication.SignOut(); Response.Redirect("logon.aspx", true); }
Assicurarsi che il codice seguente venga aggiunto al
InitializeComponent
metodo nel codice generato da Progettazione Web Form:this.cmdSignOut.ServerClick += new System.EventHandler(this.cmdSignOut_ServerClick);
Salvare e compilare il progetto. È ora possibile usare l'applicazione.
Note aggiuntive
È possibile archiviare le password in modo sicuro in un database. È possibile usare la funzione di
FormsAuthentication
utilità di classe denominataHashPasswordForStoringInConfigFile
per crittografare le password prima di archiviarle nel database o nel file di configurazione.È possibile archiviare le informazioni di connessione SQL nel file di configurazione (Web.config) in modo da poterle modificare facilmente, se necessario.
È possibile prendere in considerazione l'aggiunta di codice per impedire agli hacker che tentano di usare diverse combinazioni di password dall'accesso. Ad esempio, è possibile includere la logica che accetta solo due o tre tentativi di accesso. Se gli utenti non riescono ad accedere in alcuni tentativi, è possibile impostare un flag nel database per non consentire l'accesso fino a quando gli utenti non riabilitano gli account visitando una pagina diversa o chiamando la riga di supporto. Inoltre, è necessario aggiungere la gestione degli errori appropriata, se necessario.
Poiché l'utente viene identificato in base al cookie di autenticazione, è possibile usare Secure Sockets Layer (SSL) in questa applicazione in modo che nessuno possa ingannare il cookie di autenticazione e qualsiasi altra informazione preziosa che viene trasmessa.
L'autenticazione basata su moduli richiede che il client accetti o abiliti i cookie nel browser.
Il parametro di timeout della
<authentication>
sezione di configurazione controlla l'intervallo in cui viene rigenerato il cookie di autenticazione. È possibile scegliere un valore che offre prestazioni e sicurezza migliori.Alcuni proxy intermedi e cache su Internet possono memorizzare nella cache le risposte del server Web contenenti
Set-Cookie
intestazioni, che vengono quindi restituite a un utente diverso. Poiché l'autenticazione basata su form usa un cookie per autenticare gli utenti, questo comportamento può causare la rappresentazione accidentale (o intenzionale) di un altro utente tramite la ricezione di un cookie da un proxy intermedio o da una cache non originariamente destinata a tali utenti.