Al momento sei offline in attesa che la connessione Internet venga ristabilita

Implementazione dell'autenticazione basata su form in un'applicazione ASP.NET con Visual Basic .NET

Questo articolo è stato precedentemente pubblicato con il codice di riferimento I308157
Sommario
In questo articolo viene spiegato come implementare l'autenticazione basata su form utilizzando un database per l'archiviazione degli utenti.

Torna all'inizio

Requisiti

Nell'elenco riportato di seguito sono indicati l'hardware, il software, l'infrastruttura di rete e i service pack necessari:
  • Microsoft Visual Studio .NET
  • Microsoft SQL Server
  • Microsoft Internet Information Services (IIS) 5.0 o versioni successive
Torna all'inizio

Creare un'applicazione ASP.NET con Visual Basic .NET

  1. Aprire Visual Studio .NET.
  2. Creare una nuova applicazione Web ASP.NET e specificarne il nome e il percorso.
Torna all'inizio

Configurare le impostazioni di protezione nel file Web.config

In questa sezione viene illustrato come aggiungere e modificare le sezioni di configurazione <authentication> e <authorization> per configurare l'applicazione ASP.NET in modo che venga utilizzata l'autenticazione basata su form.
  1. Aprire il file Web.config in Esplora soluzioni.
  2. Modificare la modalità di autenticazione in Form.
  3. Inserire il tag <Forms> e immettere gli attributi corretti. Per ulteriori informazioni su questi attributi, fare riferimento alla documentazione di MSDN o QuickStart riportata nella sezione RIFERIMENTI. Copiare il codice riportato di seguito, quindi scegliere Incolla come HTML nel menu Modifica per incollare il codice nella sezione <authentication> del file:
    <authentication mode="Forms">	<forms name=".ASPXFORMSDEMO" loginUrl="logon.aspx" 	protection="All" path="/" timeout="30" /></authentication>					
  4. Impedire l'accesso a utenti anonimi nella sezione <authorization> nel modo indicato di seguito:
    <authorization>	<deny users ="?" />	<allow users = "*" /></authorization>					
Torna all'inizio

Creare una tabella di database di esempio per l'archiviazione di informazioni sugli utenti

In questa sezione viene spiegato come creare un database di esempio per l'archiviazione di nomi utente, password e ruolo degli utenti. Se si desidera archiviare nel database i ruoli degli utenti e implementare la protezione basata sui ruoli è necessaria un'apposita colonna.
  1. Nel menu Start di Windows scegliere Esegui e digitare notepad per aprire il Blocco note.
  2. Evidenziare il codice di script SQL riportato di seguito, fare clic con il pulsante destro del mouse su tale codice, quindi scegliere Copia. Nel Blocco note scegliere Incolla dal menu Modifica per incollare il codice riportato di seguito:
    if exists (select * from sysobjects where id = object_id(N'[dbo].[Users]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[Users]GOCREATE TABLE [dbo].[Users] (	[uname] [varchar] (15) NOT NULL ,	[Pwd] [varchar] (25) NOT NULL ,	[userRole] [varchar] (25) NOT NULL ,) ON [PRIMARY]GOALTER TABLE [dbo].[Users] WITH NOCHECK ADD 	CONSTRAINT [PK_Users] PRIMARY KEY  NONCLUSTERED 	(		[uname]	)  ON [PRIMARY] GOINSERT INTO Users values('user1','user1','Manager')INSERT INTO Users values('user2','user2','Admin')INSERT INTO Users values('user3','user3','User')GO					
  3. Salvare il file come Users.sql.
  4. Nel computer in cui è installato Microsoft SQL Server aprire Users.sql in Query Analyzer. Selezionare pubs dall'elenco di database, quindi eseguire lo script. Verrà creata una tabella utenti di esempio che sarà inserita nel database Pubs per l'utilizzo con l'applicazione di esempio.
Torna all'inizio

Creare una pagina Logon.aspx

  1. Aggiungere al progetto un nuovo Web Form denominato Logon.aspx.
  2. Aprire la pagina Logon.aspx nell'editor e passare alla visualizzazione HTML.
  3. Copiare il codice riportato di seguito, quindi scegliere Incolla come HTML dal menu Modifica per inserire il codice tra i tag <form>:
    <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 Web Form viene utilizzato per visualizzare un form di accesso in cui gli utenti possano specificare nome utente e password per accedere all'applicazione.
  4. Passare alla visualizzazione Progettazione e salvare la pagina.
Torna all'inizio

Scrivere il codice del gestore eventi in modo che effettui la convalida delle credenziali degli utenti

In questa sezione viene illustrato il codice da inserire nella pagina di codice sottostante (Logon.aspx.vb).
  1. Aprire il file Logon.aspx.vb.
  2. Importare gli spazi dei nomi necessari nel file di codice sottostante:
    Imports System.Data.SqlClientImports System.Web.Security 					
  3. Creare una funzione ValidateUser per la convalida delle credenziali utente a seconda del contenuto del database. Accertarsi di avere modificato la stringa Connection in modo che si riferisca al database corretto.
    Private Function ValidateUser(ByVal userName As String, ByVal passWord As String) As Boolean        Dim conn As SqlConnection        Dim cmd As SqlCommand        Dim lookupPassword As String        lookupPassword = Nothing        ' Check for an invalid userName.        ' userName  must not be set to nothing and must be between one and 15 characters.        If ((userName Is Nothing)) Then            System.Diagnostics.Trace.WriteLine("[ValidateUser] Input validation of userName failed.")            Return False        End If        If ((userName.Length = 0) Or (userName.Length > 15)) Then            System.Diagnostics.Trace.WriteLine("[ValidateUser] Input validation of userName failed.")            Return False        End If        ' Check for invalid passWord.        ' passWord must not be set to nothing and must be between one and 25 characters.        If (passWord Is Nothing) Then            System.Diagnostics.Trace.WriteLine("[ValidateUser] Input validation of passWord failed.")            Return False        End If        If ((passWord.Length = 0) Or (passWord.Length > 25)) Then            System.Diagnostics.Trace.WriteLine("[ValidateUser] Input validation of passWord failed.")            Return False        End If        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 the users table given a 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 = cmd.ExecuteScalar()            ' Cleanup command and connection objects.            cmd.Dispose()            conn.Dispose()        Catch ex As Exception            ' 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)        End Try        ' If no password found, return false.        If (lookupPassword Is Nothing) Then            ' You could write failed login attempts here to the event log for additional security.            Return False        End If        ' Compare lookupPassword and input passWord by using a case-sensitive comparison.        Return (String.Compare(lookupPassword, passWord, False) = 0)End Function					
  4. È possibile utilizzare uno dei due metodi riportati di seguito per generare il cookie di autenticazione basata su form e reindirizzare l'utente a una pagina appropriata dell'evento cmdLogin_ServerClick. Viene fornito il codice di esempio relativo a entrambi i metodi. Utilizzare quello più adatto alle proprie esigenze.
    • Chiamare il metodo RedirectFromLoginPage per generare automaticamente il cookie di autenticazione basata su form e reindirizzare l'utente a una pagina appropriata dell'evento cmdLogin_ServerClick:
      Private Sub cmdLogin_ServerClick(ByVal sender As Object, ByVal e As System.EventArgs) _   Handles cmdLogin.ServerClick   If ValidateUser(txtUserName.Value,txtUserPass.value) Then      FormsAuthentication.RedirectFromLoginPage(txtUserName.Value, _      chkPersistCookie.Checked)   Else      Response.Redirect("logon.aspx", True)   End IfEnd Sub						
    • Generare il ticket di autenticazione, crittografarlo, creare un cookie, aggiungerlo alla risposta e reindirizzare l'utente. Questo metodo garantisce un maggiore controllo sulla modalità di creazione del cookie. In questo caso è inoltre possibile aggiungere dati personalizzati a FormsAuthenticationTicket.
      Private Sub cmdLogin_ServerClick(ByVal sender As Object, _   ByVal e As System.EventArgs) Handles cmdLogin.ServerClick   If Validateuser(txtUserName.Value,txtUserPass.Value) Then      Dim tkt As FormsAuthenticationTicket      Dim cookiestr As String      Dim ck As HttpCookie      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) then ck.Expires=tkt.Expiration       ck.Path = FormsAuthentication.FormsCookiePath()       Response.Cookies.Add(ck)      Dim strRedirect As String      strRedirect = Request("ReturnURL")      If strRedirect <> "" Then         Response.Redirect(strRedirect, True)      Else         strRedirect = "default.aspx"         Response.Redirect(strRedirect, True)      End If   Else      Response.Redirect("logon.aspx", True)   End IfEnd Sub						
Torna all'inizio

Creare una pagina Default.aspx

In questa sezione viene creata una pagina di prova a cui vengono reindirizzati gli utenti dopo l'autenticazione. Se gli utenti visualizzano questa pagina senza avere prima effettuato l'accesso all'applicazione, vengono reindirizzati alla pagina di accesso.
  1. Rinominare la pagina WebForm1.aspx in Default.aspx e aprirla nell'editor.
  2. Passare alla visualizzazione HTML e copiare il codice riportato di seguito fra i tag <form>:
     <input type="submit" Value="SignOut" runat="server" id="cmdSignOut"> 						
    Questo pulsante viene utilizzato per disconnettersi dalla sessione di autenticazione basata su form.
  3. Passare alla visualizzazione Progettazione e salvare la pagina.
  4. Impostare gli spazi dei nomi necessari nel file di codice sottostante:
     Imports System.Web.Security 					
  5. Aprire la pagina di codice sottostante (Default.aspx.vb) e copiare il codice seguente nel gestore evento cmdSignOut_ServerClick:
    Private Sub cmdSignOut_ServerClick(ByVal sender As System.Object, ByVal e As System.EventArgs) _Handles cmdSignOut.ServerClick   FormsAuthentication.SignOut()   Response.Redirect("logon.aspx", True)End Sub					
  6. Salvare e compilare il progetto. A questo punto è possibile utilizzare l'applicazione.
Torna all'inizio

Risoluzione dei problemi

  • Per archiviare le password in modo protetto in un database, è possibile utilizzare la funzione utility della classe FormsAuthentication denominata HashPasswordForStoringInConfigFile per crittografare le password prima di archiviarle nel database o nel file di configurazione.
  • È possibile archiviare le informazioni relative alla connessione SQL nel file di configurazione (Web.config) in modo da poterle modificare facilmente se necessario.
  • Può essere utile aggiungere codice per impedire l'accesso a pirati informatici che tentano di utilizzare varie combinazioni di password. È ad esempio possibile includere una logica che accetti solo due o tre tentativi di accesso. Se l'utente non è in grado di accedere dopo un determinato numero di tentativi, è possibile impostare un flag nel database per impedirne l'accesso finché l'account dell'utente non viene riattivato visitando una pagina diversa o chiamando il servizio di assistenza. Laddove necessario, sarà opportuno aggiungere un'adeguata gestione degli errori.
  • Poiché l'utente viene autenticato in base al cookie, è possibile utilizzare SSL (Secure Sockets Layer) nell'applicazione in modo che nessuno possa recuperare il cookie di autenticazione ed altre preziose informazioni trasmesse.
  • Per l'autenticazione basata su form è necessario che nel browser del client i cookie vengano accettati o abilitati.
  • Il parametro timeout della sezione di configurazione <authentication> determina l'intervallo di tempo dopo il quale il cookie di autenticazione viene rigenerato. È possibile scegliere il valore che offre le migliori prestazioni e il maggior livello di protezione.
  • È possibile che alcuni proxy e cache intermedi in Internet memorizzino le risposte del server Web contenenti intestazioni Set-Cookie e che le restituiscano successivamente a un utente diverso. Poiché nell'autenticazione basata su form viene utilizzato un cookie per autenticare gli utenti, può accadere che un utente rappresenti accidentalmente o intenzionalmente un altro utente avendo ricevuto da proxy o cache intermedi un cookie di cui originariamente non era il destinatario.
Torna all'inizio
Riferimenti
Per informazioni sull'implementazione dell'autenticazione basata su form semplice mediante l'utilizzo della sezione <credentials> per memorizzare gli utenti e le password, consultare il seguente articolo negli esempi di ASP.NET QuickStart (informazioni in lingua inglese): Per informazioni su come implementare l'autenticazione basata su form che utilizza un file XML (Extensible Markup Language) per archiviare utenti e password, vedere il seguente argomento della documentazione di .NET Framework Software Development Kit (SDK) (informazioni in lingua inglese): Per ulteriori informazioni sulla protezione delle applicazioni Web ASP.NET, vedere il seguente articolo della documentazione .NET Framework SDK (informazioni in lingua inglese): Per ulteriori informazioni sullo spazio dei nomi System.Web.Security, vedere il seguente articolo della documentazione di .NET Framework SDK (informazioni in lingua inglese): Per ulteriori informazioni sulla configurazione di ASP.NET, vedere i seguenti articoli della documentazione di .NET Framework SDK (informazioni in lingua inglese): Per informazioni e linee guida sulla protezione in ASP.NET, consultare il seguente white paper MSDN (informazioni in lingua inglese):
Autenticazione in ASP.NET: regole per la protezione di .NET
http://msdn2.microsoft.com/en-us/library/ms978378.aspx
Per ulteriori informazioni a carattere generale su ASP.NET, fare riferimento al seguente newsgroup MSDN: Per ulteriori informazioni, fare riferimento ai testi seguenti (informazioni in lingua inglese):
Esposito, Dino. Progettare soluzioni Web con ASP.NET e ADO.NET. Microsoft Press, 2001.

Howard, Michael and David LeBlanc. Creare codice sicuro. Microsoft Press, 2001.
Torna all'inizio
autenticazione basata su form
Proprietà

ID articolo: 308157 - Ultima revisione: 10/29/2007 14:53:46 - Revisione: 8.9

Microsoft ASP.NET 1.1, Microsoft ASP.NET 1.0, Microsoft Visual Basic .NET 2003 Standard Edition, Microsoft Visual Basic .NET 2002 Standard Edition, Microsoft SQL Server 7.0 Standard Edition, Microsoft SQL Server 2000 Standard Edition

  • kbproductlink kbconfig kbhowtomaster kbsecurity kbweb KB308157
Feedback
nt.createElement('meta');m.name='ms.dqp0';m.content='true';document.getElementsByTagName('head')[0].appendChild(m);" onload="var m=document.createElement('meta');m.name='ms.dqp0';m.content='false';document.getElementsByTagName('head')[0].appendChild(m);" src="http://c1.microsoft.com/c.gif?"> 1&t=">