Creazione di account utente (C#)

di Scott Mitchell

Nota

Poiché questo articolo è stato scritto, i provider di appartenenza ASP.NET sono stati sostituiti da ASP.NET Identity. È consigliabile aggiornare le app per usare la ASP.NET Identity Platform anziché i provider di appartenenza in primo piano al momento della scrittura di questo articolo. ASP.NET Identity offre numerosi vantaggi rispetto al sistema di appartenenza ASP.NET, tra cui :

  • Prestazioni migliori
  • Miglioramento dell'estendibilità e della testability
  • Supporto per OAuth, OpenID Connect e autenticazione a due fattori
  • Supporto delle identità basate sulle attestazioni
  • Interoperabilità migliore con ASP.Net Core

Scaricare codice o scaricare pdf

In questa esercitazione verrà illustrato l'uso del framework Di appartenenza (tramite SqlMembershipProvider) per creare nuovi account utente. Verrà illustrato come creare nuovi utenti a livello di codice e tramite ASP. Controllo CreateUserWizard predefinito di NET.

Introduzione

Nell'esercitazione precedente è stato installato lo schema dei servizi applicazione in un database, che ha aggiunto le tabelle, le viste e le stored procedure necessarie da SqlMembershipProvider e SqlRoleProvider. Questa infrastruttura ha creato l'infrastruttura necessaria per il resto delle esercitazioni in questa serie. In questa esercitazione verrà illustrato l'uso del framework di appartenenza (tramite ) SqlMembershipProviderper creare nuovi account utente. Verrà illustrato come creare nuovi utenti a livello di codice e tramite ASP. Controllo CreateUserWizard predefinito di NET.

Oltre a imparare a creare nuovi account utente, sarà anche necessario aggiornare il sito Web demo creato prima nell'esercitazione Panoramica dell'autenticazione dei moduli e quindi migliorata nell'esercitazione Configurazione autenticazione moduli e Argomenti avanzati. L'applicazione Web demo include una pagina di accesso che convalida le credenziali degli utenti rispetto alle coppie nome utente/password hardcoded. Include inoltre Global.asax il codice che crea oggetti e IIdentity personalizzati IPrincipal per gli utenti autenticati. Verrà aggiornata la pagina di accesso per convalidare le credenziali degli utenti nel framework di appartenenza e rimuovere l'entità e la logica di identità personalizzata.

È possibile iniziare subito.

Elenco di controllo autenticazione e appartenenza dei moduli

Prima di iniziare a lavorare con il framework di appartenenza, è necessario esaminare i passaggi importanti eseguiti per raggiungere questo punto. Quando si usa il framework di appartenenza con SqlMembershipProvider in uno scenario di autenticazione basato su moduli, è necessario eseguire i passaggi seguenti prima di implementare le funzionalità di appartenenza nell'applicazione Web:

  1. Abilitare l'autenticazione basata su moduli. Come illustrato in Panoramica dell'autenticazione dei moduli, l'autenticazione dei moduli è abilitata modificando e impostando Web.config l'attributo <authentication> dell'elemento mode su Forms. Con l'autenticazione dei moduli abilitata, ogni richiesta in ingresso viene esaminata per un ticket di autenticazione dei moduli, che, se presente, identifica il richiedente.
  2. Aggiungere lo schema dei servizi applicazione al database appropriato. Quando si usa l'elemento SqlMembershipProvider necessario per installare lo schema dei servizi applicazioni in un database. In genere questo schema viene aggiunto allo stesso database che contiene il modello di dati dell'applicazione. L'esercitazione Creazione dello schema di appartenenza in SQL Server ha esaminato l'uso dello aspnet_regsql.exe strumento per eseguire questa operazione.
  3. Personalizzare le impostazioni dell'applicazione Web per fare riferimento al database dal passaggio 2. L'esercitazione Creazione dello schema di appartenenza in SQL Server mostra due modi per configurare l'applicazione Web in modo che il SqlMembershipProvider database venga usato nel passaggio 2: modificando il LocalSqlServer nome della stringa di connessione oppure aggiungendo un nuovo provider registrato all'elenco dei provider di framework di appartenenza e personalizzando tale nuovo provider per l'uso del database dal passaggio 2.

Quando si compila un'applicazione Web che usa l'autenticazione SqlMembershipProvider basata su moduli e, è necessario eseguire questi tre passaggi prima di usare la classe o i Membership controlli Web di accesso ASP.NET. Poiché questi passaggi sono già stati eseguiti nelle esercitazioni precedenti, è possibile iniziare a usare il framework di appartenenza.

Passaggio 1: Aggiunta di nuove pagine ASP.NET

In questa esercitazione e i tre successivi verranno esaminate diverse funzioni e funzionalità correlate all'appartenenza. È necessaria una serie di pagine di ASP.NET per implementare gli argomenti esaminati in queste esercitazioni. Creare queste pagine e quindi un file (Web.sitemap)della mappa del sito.

Iniziare creando una nuova cartella nel progetto denominato Membership. Aggiungere quindi cinque nuove pagine ASP.NET alla Membership cartella, collegando ogni pagina alla Site.master pagina master. Assegnare un nome alle pagine:

  • CreatingUserAccounts.aspx
  • UserBasedAuthorization.aspx
  • EnhancedCreateUserWizard.aspx
  • AdditionalUserInfo.aspx
  • Guestbook.aspx

A questo punto la Esplora soluzioni del progetto dovrebbe essere simile alla schermata visualizzata nella figura 1.

Cinque nuove pagine sono state aggiunte alla cartella di appartenenza

Figura 1: Cinque nuove pagine sono state aggiunte alla cartella (fare clic per visualizzare l'immagineMembership a dimensioni complete)

Ogni pagina deve, a questo punto, avere i due controlli Contenuto, uno per ognuno dei ContentPlaceHolder della pagina master: MainContent e LoginContent.

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"

Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="LoginContent"
Runat="Server">
</asp:Content>

Tenere presente che il LoginContent markup predefinito di ContentPlaceHolder visualizza un collegamento per accedere o disconnettersi dal sito, a seconda che l'utente sia autenticato. La presenza del controllo Contenuto, tuttavia, esegue l'override del Content2 markup predefinito della pagina master. Come illustrato in Un'esercitazione Panoramica dell'autenticazione dei moduli , questa operazione è utile nelle pagine in cui non si desidera visualizzare le opzioni correlate all'accesso nella colonna sinistra.

Per queste cinque pagine, tuttavia, si vuole visualizzare il markup predefinito della pagina master per LoginContent ContentPlaceHolder. Rimuovere pertanto il markup dichiarativo per il Content2 controllo Contenuto. Dopo aver eseguito questa operazione, ogni markup di cinque pagine deve contenere un solo controllo Contenuto.

Passaggio 2: Creazione della mappa del sito

Tutti i siti Web più semplici devono implementare una forma di interfaccia utente di navigazione. L'interfaccia utente di spostamento può essere un semplice elenco di collegamenti alle varie sezioni del sito. In alternativa, questi collegamenti possono essere disposti in menu o viste ad albero. Come sviluppatori di pagine, la creazione dell'interfaccia utente di navigazione è solo metà della storia. Abbiamo anche bisogno di alcuni mezzi per definire la struttura logica del sito in modo gestibile e aggiornabile. Man mano che le nuove pagine vengono aggiunte o esistenti rimosse, si vuole essere in grado di aggiornare un'unica origine, ovvero la mappa del sito, e avere tali modifiche riflesse nell'interfaccia utente di spostamento del sito.

Queste due attività, che definiscono la mappa del sito e implementano un'interfaccia utente di navigazione basata sulla mappa del sito, sono facili da eseguire grazie al framework Mappa siti e ai controlli Web di spostamento aggiunti in ASP.NET versione 2.0. Il framework Mappa siti consente a uno sviluppatore di definire una mappa del sito e quindi di accedervi tramite un'API programmatica (classeSiteMap). I controlli Web di spostamento predefiniti includono un controllo Menu, il controllo TreeView e il controllo SiteMapPath.

Come i framework Di appartenenza e ruoli, il framework Mappa siti viene compilato in cima al modello del provider. Il processo della classe provider Mappa siti consiste nel generare la struttura in memoria utilizzata dalla SiteMap classe da un archivio dati persistente, ad esempio un file XML o una tabella di database. .NET Framework viene fornito con un provider di mappe siti predefinito che legge i dati della mappa del sito da un file XML (XmlSiteMapProvider) e questo è il provider che verrà usato in questa esercitazione. Per alcune implementazioni del provider di Mappe siti alternative, vedere la sezione Ulteriori letture alla fine di questa esercitazione.

Il provider mappa siti predefinito prevede che un file XML formattato correttamente denominato Web.sitemap esista nella directory radice. Poiché si usa questo provider predefinito, è necessario aggiungere un file di questo tipo e definire la struttura della mappa del sito nel formato XML appropriato. Per aggiungere il file, fare clic con il pulsante destro del mouse sul nome del progetto in Esplora soluzioni e scegliere Aggiungi nuovo elemento. Nella finestra di dialogo scegliere di aggiungere un file di tipo Mappa siti denominato Web.sitemap.

Aggiungere un file denominato Web.sitemap alla directory radice del progetto

Figura 2: Aggiungere un file denominato Web.sitemap alla directory radice del progetto (fare clic per visualizzare l'immagine full-size)

Il file della mappa del sito XML definisce la struttura del sito Web come gerarchia. Questa relazione gerarchica viene modellata nel file XML tramite l'origine degli <siteMapNode> elementi. Deve Web.sitemap iniziare con un <siteMap> nodo padre che ha esattamente un <siteMapNode> elemento figlio. Questo elemento di primo livello <siteMapNode> rappresenta la radice della gerarchia e può avere un numero arbitrario di nodi discendenti. Ogni elemento deve includere un title attributo e può includere url facoltativamente e description attributi, tra gli altri. Ogni <siteMapNode> attributo non vuoto url deve essere univoco.

Immettere il codice XML seguente nel Web.sitemap file:

<?xml version="1.0" encoding="utf-8" ?>

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
     <siteMapNode url="~/Default.aspx" title="Home">
          <siteMapNode title="Membership">
               <siteMapNode url="~/Membership/CreatingUserAccounts.aspx" title="Creating User Accounts" />

               <siteMapNode url="~/Membership/UserBasedAuthorization.aspx" title="User-Based Authorization" />
               <siteMapNode url="~/Membership/Guestbook.aspx" title="Storing Additional User Information" />
          </siteMapNode>

     </siteMapNode>
</siteMap>

Il markup della mappa del sito precedente definisce la gerarchia illustrata nella figura 3.

La mappa del sito rappresenta una struttura di navigazione gerarchica

Figura 3: La mappa del sito rappresenta una struttura di navigazione gerarchica (fare clic per visualizzare l'immagine full-size)

Passaggio 3: Aggiornamento della pagina master per includere un'interfaccia utente di spostamento

ASP.NET include numerosi controlli Web correlati alla navigazione per la progettazione di un'interfaccia utente. Includono i controlli Menu, TreeView e SiteMapPath. I controlli Menu e TreeView eseguono rispettivamente il rendering della struttura della mappa del sito in un menu o in un albero, mentre SiteMapPath visualizza un riquadro di navigazione che mostra il nodo corrente visitato e i relativi predecessori. I dati della mappa del sito possono essere associati ad altri controlli Web dati usando SiteMapDataSource e possono essere accessibili a livello di codice tramite la SiteMap classe .

Poiché una discussione approfondita del framework Mappa siti e dei controlli di spostamento è oltre l'ambito di questa serie di esercitazioni, anziché dedicare tempo alla creazione di un'interfaccia utente di navigazione personalizzata, è invece possibile prendere in prestito quella usata nella serie di esercitazioni Working with Data in ASP.NET 2.0 , che usa un controllo Repeater per visualizzare un elenco a due puntini profondi dei collegamenti di spostamento, come illustrato nella figura 4.

Per creare questa interfaccia, aggiungere il markup dichiarativo seguente alla Site.master colonna sinistra della pagina master in cui il testo "TODO: Menu verrà visualizzato qui..." attualmente risiede.

<ul>
     <li>

          <asp:HyperLink runat="server" ID="lnkHome" NavigateUrl="~/Default.aspx">Home</asp:HyperLink>
     </li>
     <asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1">

          <ItemTemplate>
               <li>
                    <asp:HyperLink ID="lnkMenuItem" runat="server" 
                         NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>

                    <asp:Repeater ID="submenu" runat="server" DataSource="<%#
                         ((SiteMapNode) Container.DataItem).ChildNodes %>">
                         <HeaderTemplate>
                              <ul>
                         </HeaderTemplate>
                         <ItemTemplate>

                              <li>
                                   <asp:HyperLink ID="lnkMenuItem" runat="server" NavigateUrl='<%#
                                        Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>

                              </li>
                         </ItemTemplate>
                         <FooterTemplate>
                              </ul>
                         </FooterTemplate>
                    </asp:Repeater>
               </li>
          </ItemTemplate>
     </asp:Repeater>

</ul>
    
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false" />

Il markup precedente associa un controllo Repeater denominato menu a SiteMapDataSource, che restituisce la gerarchia della mappa del sito definita in Web.sitemap. Poiché la proprietà del ShowStartingNode controllo SiteMapDataSource è impostata su False, viene avviata la restituzione della gerarchia della mappa del sito a partire dai discendenti del nodo "Home". Il ripetitore visualizza ognuno di questi nodi (attualmente "Appartenenza") in un <li> elemento. Un altro ripetitore interno visualizza quindi i figli del nodo corrente in un elenco non ordinato annidato.

La figura 4 mostra l'output di rendering del markup precedente con la struttura della mappa del sito creata nel passaggio 2. Il ripetitore esegue il rendering del markup elenco non ordinato di vaniglia; le regole del foglio di stile a cascata definite in Styles.css sono responsabili del layout esteticamente piacevole. Per una descrizione più dettagliata del funzionamento del markup precedente, vedere l'esercitazione Relativa alle pagine master e alla navigazione sito .

L'interfaccia utente di spostamento viene eseguito il rendering tramite elenchi non ordinati annidati

Figura 4: Viene eseguito il rendering dell'interfaccia utente di spostamento usando elenchi non ordinati annidati (fare clic per visualizzare l'immagine a dimensioni complete)

Aggiunta di spostamento di breadcrumb

Oltre all'elenco di collegamenti nella colonna a sinistra, è anche possibile visualizzare ogni pagina con un pane grattugiato. Un panecrumb è un elemento dell'interfaccia utente di navigazione che mostra rapidamente agli utenti la loro posizione corrente all'interno della gerarchia del sito. Il controllo SiteMapPath usa il framework Mappa sito per determinare la posizione della pagina corrente nella mappa del sito e quindi visualizza un panecrumb in base a queste informazioni.

In particolare, aggiungere un <span> elemento all'elemento intestazione <div> della pagina master e impostare l'attributo del class nuovo <span> elemento su "breadcrumb". La Styles.css classe contiene una regola per una classe "breadcrumb". Aggiungere quindi un SiteMapPath a questo nuovo <span> elemento.

<div id="header">
     <span class="title">User Account Tutorials</span><br />
     <span class="breadcrumb">
          <asp:SiteMapPath ID="SiteMapPath1" runat="server">

          </asp:SiteMapPath>
     </span>
</div>

La figura 5 mostra l'output di SiteMapPath quando si visita ~/Membership/CreatingUserAccounts.aspx.

Il panecrumb visualizza la pagina corrente e i relativi predecessori nella mappa del sito

Figura 5: Il panecrumb visualizza la pagina corrente e i relativi predecessori nella mappa del sito (fare clic per visualizzare l'immagine full-size)

Passaggio 4: Rimozione della logica di entità e identità personalizzata

Gli oggetti entità e identità personalizzati possono essere associati all'utente autenticato. Questa operazione è stata eseguita creando un gestore eventi in Global.asax per l'evento dell'applicazione PostAuthenticateRequest , che viene generato dopo l'autenticazione FormsAuthenticationModule dell'utente. In questo gestore eventi sono stati sostituiti gli GenericPrincipal oggetti e aggiunti dall'oggetto FormsAuthenticationModule con gli CustomPrincipal oggetti e FormsIdentityCustomIdentity creati in tale esercitazione.

Anche se gli oggetti entità e identità personalizzati sono utili in determinati scenari, nella maggior parte dei casi gli GenericPrincipal oggetti e FormsIdentity sono sufficienti. Di conseguenza, credo che sarebbe utile tornare al comportamento predefinito. Apportare questa modifica rimuovendo o commentando il PostAuthenticateRequest gestore eventi o eliminando completamente il Global.asax file.

Passaggio 5: Creazione a livello di codice di un nuovo utente

Per creare un nuovo account utente tramite il framework Membership, usare il Membership metodo della CreateUserclasse. Questo metodo include parametri di input per il nome utente, la password e altri campi correlati all'utente. Nella chiamata, delega la creazione del nuovo account utente al provider di appartenenza configurato e quindi restituisce un MembershipUser oggetto che rappresenta l'account utente appena creato.

Il CreateUser metodo ha quattro overload, ognuno accettando un numero diverso di parametri di input:

Questi quattro overload differiscono sulla quantità di informazioni raccolte. Il primo overload, ad esempio, richiede solo il nome utente e la password per il nuovo account utente, mentre il secondo richiede anche l'indirizzo di posta elettronica dell'utente.

Questi overload esistono perché le informazioni necessarie per creare un nuovo account utente dipendono dalle impostazioni di configurazione del provider di appartenenza. Nell'esercitazione Creazione dello schema di appartenenza in SQL Server è stata esaminata la specifica delle impostazioni di configurazione del provider di appartenenza in Web.config. La tabella 2 includeva un elenco completo delle impostazioni di configurazione.

Un'impostazione di configurazione del provider di appartenenza che influisce sugli CreateUser overload che possono essere usati è l'impostazione requiresQuestionAndAnswer . Se requiresQuestionAndAnswer è impostato su true (impostazione predefinita), quando si crea un nuovo account utente è necessario specificare una domanda di sicurezza e una risposta. Queste informazioni vengono usate in un secondo momento se l'utente deve reimpostare o modificare la password. In particolare, in quel momento vengono visualizzate le domande di sicurezza e devono immettere la risposta corretta per reimpostare o modificare la password. Di conseguenza, se l'oggetto è impostato su, la chiamata a true una delle prime due CreateUser overload comporta un'eccezione requiresQuestionAndAnswer perché la domanda di sicurezza e la risposta sono mancanti. Poiché l'applicazione è attualmente configurata per richiedere una domanda e una risposta alla sicurezza, sarà necessario usare uno degli ultimi due overload durante la creazione a livello di codice dell'utente.

Per illustrare l'uso del CreateUser metodo, verrà creata un'interfaccia utente in cui viene richiesto all'utente il nome, la password, la posta elettronica e una risposta a una domanda di sicurezza predefinita. Aprire la CreatingUserAccounts.aspx pagina nella Membership cartella e aggiungere i controlli Web seguenti al controllo Contenuto:

  • Casella di testo denominata Username
  • TextBox denominato Password, la cui TextMode proprietà è impostata su Password
  • Casella di testo denominata Email
  • Etichetta denominata SecurityQuestion con la relativa Text proprietà deselezionata
  • Casella di testo denominata SecurityAnswer
  • Pulsante denominato CreateAccountButton la cui proprietà Text è impostata su "Crea l'account utente"
  • Controllo Label denominato CreateAccountResults con la relativa Text proprietà deselezionata

A questo punto la schermata dovrebbe essere simile alla schermata visualizzata nella figura 6.

Aggiungere i vari controlli Web alla pagina CreateUserAccounts.aspx

Figura 6: Aggiungere i vari controlli Web alla CreatingUserAccounts.aspx pagina (fare clic per visualizzare l'immagine a dimensioni complete)

Etichetta SecurityQuestion e SecurityAnswer Casella di testo sono destinati a visualizzare una domanda di sicurezza predefinita e raccogliere la risposta dell'utente. Si noti che sia la domanda di sicurezza che la risposta vengono archiviate su base utente, quindi è possibile consentire a ogni utente di definire la propria domanda di sicurezza. Tuttavia, per questo esempio ho deciso di usare una domanda di sicurezza universale, vale a dire: "Qual è il tuo colore preferito?"

Per implementare questa domanda di sicurezza predefinita, aggiungere una costante alla classe code-behind della pagina denominata passwordQuestion, assegnandole la domanda di sicurezza. Quindi, nel Page_Load gestore eventi assegnare questa costante alla SecurityQuestion proprietà dell'etichetta Text :

const string passwordQuestion = "What is your favorite color";
    
protected void Page_Load(object sender, EventArgs e)
{
     if (!Page.IsPostBack)
          SecurityQuestion.Text = passwordQuestion;
}

Creare quindi un gestore eventi per l'evento CreateAccountButtone Click aggiungere il codice seguente:

protected void CreateAccountButton_Click(object sender, EventArgs e)
{
     MembershipCreateStatus createStatus;
     MembershipUser newUser = Membership.CreateUser(Username.Text, Password.Text, Email.Text, passwordQuestion, SecurityAnswer.Text, true, out createStatus);
     switch (createStatus)
     {
          case MembershipCreateStatus.Success:
               CreateAccountResults.Text = "The user account was successfully created!";
               break;
          case MembershipCreateStatus.DuplicateUserName:
               CreateAccountResults.Text = "There already exists a user with this username.";
               break;

          case MembershipCreateStatus.DuplicateEmail:
               CreateAccountResults.Text = "There already exists a user with this email address.";
               break;
          case MembershipCreateStatus.InvalidEmail:
               CreateAccountResults.Text = "There email address you provided in invalid.";
               break;
          case MembershipCreateStatus.InvalidAnswer:
               CreateAccountResults.Text = "There security answer was invalid.";
               break;
          case MembershipCreateStatus.InvalidPassword:
               CreateAccountResults.Text = "The password you provided is invalid. It must be seven characters long and have at least one non-alphanumeric character.";

               break;
          default:
               CreateAccountResults.Text = "There was an unknown error; the user account was NOT created.";
               break;
     }
}

Il Click gestore eventi inizia definendo una variabile denominata createStatus di tipo MembershipCreateStatus. MembershipCreateStatus è un'enumerazione che indica lo stato dell'operazione CreateUser . Ad esempio, se l'account utente viene creato correttamente, l'istanza risultante MembershipCreateStatus verrà impostata su un valore di Success; se l'operazione ha esito negativo perché esiste già un utente con lo stesso nome utente, verrà impostato su un valore di DuplicateUserName. Nell'overload usato è necessario passare un'istanza CreateUserMembershipCreateStatus al metodo come out parametro. Questo parametro è impostato sul valore appropriato all'interno del CreateUser metodo ed è possibile esaminare il relativo valore dopo la chiamata al metodo per determinare se l'account utente è stato creato correttamente.

CreateUserDopo aver chiamato , passando createStatus, viene usata un'istruzione switch per restituire un messaggio appropriato a seconda del valore assegnato a createStatus. Le figure 7 mostrano l'output quando è stato creato correttamente un nuovo utente. Le figure 8 e 9 mostrano l'output quando l'account utente non viene creato. Nella figura 8 il visitatore ha immesso una password di cinque lettere, che non soddisfa i requisiti di forza della password specificati nelle impostazioni di configurazione del provider di appartenenza. Nella figura 9 il visitatore tenta di creare un account utente con un nome utente esistente (quello creato nella figura 7).

Viene creato correttamente un nuovo account utente

Figura 7: Viene creato correttamente un nuovo account utente (fare clic per visualizzare l'immagine full-size)

L'account utente non viene creato perché la password specificata è troppo debole

Figura 8: l'account utente non viene creato perché la password specificata è troppo debole (fare clic per visualizzare l'immagine a dimensioni complete)

L'account utente non viene creato perché il nome utente è già in uso

Figura 9: l'account utente non viene creato perché il nome utente è già in uso (fare clic per visualizzare l'immagine full-size)

Nota

Si potrebbe chiedersi come determinare l'esito positivo o l'errore quando si usa uno dei primi due CreateUser overload del metodo, nessuno dei quali ha un parametro di tipo MembershipCreateStatus. Questi primi due overload generano un'eccezioneMembershipCreateUserException in caso di errore, che include una StatusCode proprietà di tipo MembershipCreateStatus.

Dopo aver creato alcuni account utente, verificare che gli account siano stati creati elencando il contenuto delle aspnet_Users tabelle e aspnet_Membership nel SecurityTutorials.mdf database. Come illustrato nella figura 10, ho aggiunto due utenti tramite la CreatingUserAccounts.aspx pagina: Tito e Bruce.

Ci sono due utenti nell'archivio utenti di appartenenza: Tito e Bruce

Figura 10: Ci sono due utenti nell'Archivio utenti di appartenenza: Tito e Bruce (Fare clic per visualizzare l'immagine a dimensioni complete)

Mentre l'archivio utenti di appartenenza include ora le informazioni sull'account di Bruce e Tito, dobbiamo ancora implementare funzionalità che consente a Bruce o Tito di accedere al sito. Attualmente, Login.aspx convalida le credenziali dell'utente rispetto a un set hardcoded di coppie nome utente/password. Non convalida le credenziali fornite nel framework di appartenenza. Per visualizzare ora i nuovi account utente nelle aspnet_Users tabelle e aspnet_Membership dovranno essere sufficienti. Nell'esercitazione successiva, convalidare le credenziali utente rispetto all'archivio utenti di appartenenza, verrà aggiornata la pagina di accesso per convalidare l'archivio appartenenza.

Nota

Se non vengono visualizzati utenti nel SecurityTutorials.mdf database, è possibile che l'applicazione Web usi il provider di appartenenza predefinito, , AspNetSqlMembershipProviderche usa il ASPNETDB.mdf database come archivio utenti. Per determinare se si tratta del problema, fare clic sul pulsante Aggiorna nella Esplora soluzioni. Se alla cartella è stato aggiunto App_Data un database denominatoASPNETDB.mdf, si tratta del problema. Tornare al passaggio 4 dell'esercitazioneCreazione dello schema di appartenenza in SQL Server per istruzioni su come configurare correttamente il provider di appartenenza.

Nella maggior parte degli scenari di account utente, il visitatore viene presentato con un'interfaccia per immettere il nome utente, la password, la posta elettronica e altre informazioni essenziali, a quel punto viene creato un nuovo account. In questo passaggio è stata esaminata la creazione di un'interfaccia di questo tipo per mano e quindi è stato illustrato come usare il metodo per aggiungere a livello di codice il Membership.CreateUser nuovo account utente in base agli input dell'utente. Il codice, tuttavia, ha appena creato il nuovo account utente. Non è stata eseguita alcuna azione di completamento, ad esempio l'accesso all'utente al sito nell'account utente appena creato o l'invio di un messaggio di posta elettronica di conferma all'utente. Questi passaggi aggiuntivi richiedono codice aggiuntivo nel gestore eventi del Click pulsante.

ASP.NET viene fornito con il controllo CreateUserWizard, progettato per gestire il processo di creazione dell'account utente, dal rendering di un'interfaccia utente per la creazione di nuovi account utente, alla creazione dell'account nel framework di appartenenza e all'esecuzione di attività di creazione post-account, ad esempio l'invio di un messaggio di posta elettronica di conferma e la registrazione dell'utente appena creato nel sito. L'uso del controllo CreateUserWizard è semplice come trascinare il controllo CreateUserWizard dalla casella degli strumenti in una pagina e quindi impostare alcune proprietà. Nella maggior parte dei casi, non sarà necessario scrivere una singola riga di codice. Questo controllo nifty verrà esaminato in dettaglio nel passaggio 6.

Se i nuovi account utente vengono creati solo tramite una tipica pagina Web Create Account, è improbabile che sia mai necessario scrivere codice che usa il CreateUser metodo, poiché il controllo CreateUserWizard probabilmente soddisfa le proprie esigenze. Tuttavia, il CreateUser metodo è utile negli scenari in cui è necessaria un'esperienza utente create account altamente personalizzata o quando è necessario creare nuovi account utente a livello di codice tramite un'interfaccia alternativa. Ad esempio, potrebbe essere presente una pagina che consente a un utente di caricare un file XML contenente le informazioni utente da un'altra applicazione. La pagina potrebbe analizzare il contenuto del file XML caricato e creare un nuovo account per ogni utente rappresentato nel codice XML chiamando il CreateUser metodo .

Passaggio 6: Creazione di un nuovo utente con il controllo CreateUserWizard

ASP.NET viene fornito con diversi controlli Web di accesso. Questi controlli consentono molti scenari comuni relativi all'account utente e all'accesso. Il controllo CreateUserWizard è un controllo di questo tipo progettato per presentare un'interfaccia utente per l'aggiunta di un nuovo account utente al framework di appartenenza.

Come molti altri controlli Web correlati all'account di accesso, è possibile usare CreateUserWizard senza scrivere una singola riga di codice. Fornisce in modo intuitivo un'interfaccia utente basata sulle impostazioni di configurazione del provider di appartenenze e chiama internamente il Membership metodo della CreateUser classe dopo che l'utente immette le informazioni necessarie e fa clic sul pulsante "Crea utente". Il controllo CreateUserWizard è estremamente personalizzabile. Ci sono una serie di eventi che vengono attivati durante varie fasi del processo di creazione dell'account. È possibile creare gestori eventi, in base alle esigenze, per inserire logica personalizzata nel flusso di lavoro di creazione dell'account. Inoltre, l'aspetto di CreateUserWizard è molto flessibile. Esistono diverse proprietà che definiscono l'aspetto dell'interfaccia predefinita; se necessario, è possibile convertire il controllo in un modello o aggiungere ulteriori "passaggi" di registrazione utente.

Si inizierà con un'analisi usando l'interfaccia e il comportamento predefiniti del controllo CreateUserWizard. Si esaminerà quindi come personalizzare l'aspetto tramite le proprietà e gli eventi del controllo.

Esame dell'interfaccia e del comportamento predefiniti di CreateUserWizard

Tornare alla CreatingUserAccounts.aspx pagina nella Membership cartella, passare alla modalità Progettazione o Dividi e quindi aggiungere un controllo CreateUserWizard nella parte superiore della pagina. Il controllo CreateUserWizard viene archiviato nella sezione Controlli di accesso della casella degli strumenti. Dopo aver aggiunto il controllo, impostarne la ID proprietà su RegisterUser. Come illustrato nella figura 11, createUserWizard esegue il rendering di un'interfaccia con caselle di testo per il nome utente, la password, l'indirizzo di posta elettronica e la risposta e la domanda e la risposta del nuovo utente.

Il controllo CreateUserWizard esegue il rendering di un'interfaccia utente di creazione generica

Figura 11: Il controllo CreateUserWizard esegue il rendering di un'interfaccia utente di creazione generica (fare clic per visualizzare l'immagine a dimensione intera)

È ora necessario confrontare l'interfaccia utente predefinita generata dal controllo CreateUserWizard con l'interfaccia creata nel passaggio 5. Per iniziare, il controllo CreateUserWizard consente al visitatore di specificare sia la domanda di sicurezza che la risposta, mentre l'interfaccia creata manualmente ha usato una domanda di sicurezza predefinita. L'interfaccia del controllo CreateUserWizard include anche controlli di convalida, mentre era ancora necessario implementare la convalida nei campi modulo dell'interfaccia. E l'interfaccia di controllo CreateUserWizard include una casella di testo "Conferma password" (insieme a compareValidator per assicurarsi che il testo immesso nelle caselle di testo "Password" e "Confronta password" sia uguale).

È interessante notare che il controllo CreateUserWizard consulta le impostazioni di configurazione del provider di appartenenze durante il rendering dell'interfaccia utente. Ad esempio, le caselle di testo domande e risposte di sicurezza vengono visualizzate solo se requiresQuestionAndAnswer è impostato su True. Analogamente, CreateUserWizard aggiunge automaticamente un controllo RegularExpressionValidator per garantire che i requisiti di complessità della password siano soddisfatti e ne imposti le ErrorMessage proprietà e ValidationExpression in base alle minRequiredPasswordLengthimpostazioni di configurazione , minRequiredNonalphanumericCharacterse passwordStrengthRegularExpression .

Il controllo CreateUserWizard, come suggerisce il nome, è derivato dal controllo Creazione guidata. I controlli della procedura guidata sono progettati per fornire un'interfaccia per completare le attività in più passaggi. Un controllo Procedura guidata può avere un numero arbitrario di WizardSteps, ognuno dei quali è un modello che definisce i controlli HTML e Web per tale passaggio. Il controllo Procedura guidata visualizza inizialmente il primo WizardStep, insieme ai controlli di spostamento che consentono all'utente di procedere da un passaggio all'altro o di tornare ai passaggi precedenti.

Come illustrato nel markup dichiarativo nella figura 11, l'interfaccia predefinita del controllo CreateUserWizard include due WizardSteps:

  • CreateUserWizardStep : esegue il rendering dell'interfaccia per raccogliere informazioni per la creazione del nuovo account utente. Questo è il passaggio illustrato nella figura 11.
  • CompleteWizardStep : visualizza un messaggio che indica che l'account è stato creato correttamente.

L'aspetto e il comportamento di CreateUserWizard possono essere modificati convertendo uno di questi passaggi in modelli o aggiungendo il proprio WizardSteps. Si esaminerà l'aggiunta di un WizardStep all'interfaccia di registrazione nell'esercitazione Archiviazione di informazioni aggiuntive sull'utente .

Verrà ora visualizzato il controllo CreateUserWizard in azione. Visitare la CreatingUserAccounts.aspx pagina tramite un browser. Per iniziare, immettere alcuni valori non validi nell'interfaccia di CreateUserWizard. Provare a immettere una password non conforme ai requisiti di complessità della password o lasciare vuota la casella di testo "Nome utente". CreateUserWizard visualizzerà un messaggio di errore appropriato. La figura 12 mostra l'output quando si tenta di creare un utente con una password complessa insufficienti.

CreateUserWizard inserisce automaticamente i controlli di convalida

Figura 12: CreateUserWizard inserisce automaticamente i controlli di convalida (fare clic per visualizzare l'immagine a dimensione intera)

Immettere quindi i valori appropriati in CreateUserWizard e fare clic sul pulsante "Crea utente". Supponendo che i campi richiesti siano stati immessi e che il livello di attendibilità della password sia sufficiente, CreateUserWizard creerà un nuovo account utente tramite il framework di appartenenza e quindi visualizzerà l'interfaccia della password (vedere la CompleteWizardStepfigura 13). Dietro le quinte, CreateUserWizard chiama il Membership.CreateUser metodo , proprio come nel passaggio 5.

È stato creato un nuovo account utente

Figura 13: È stato creato un nuovo account utente (fare clic per visualizzare l'immagine a dimensione intera)

Nota

Come illustrato nella figura 13, l'interfaccia CompleteWizardStepdi include un pulsante Continua. Tuttavia, a questo punto facendo clic si esegue solo un postback, lasciando il visitatore nella stessa pagina. Nella sezione "Personalizzazione dell'aspetto e del comportamento di CreateUserWizard tramite le relative proprietà" esamineremo come è possibile fare in modo che questo pulsante invii il visitatore a Default.aspx (o a un'altra pagina).

Dopo aver creato un nuovo account utente, tornare a Visual Studio ed esaminare le aspnet_Users tabelle e aspnet_Membership come nella figura 10 per verificare che l'account sia stato creato correttamente.

Personalizzazione del comportamento e dell'aspetto di CreateUserWizard tramite le relative proprietà

CreateUserWizard può essere personalizzato in diversi modi, tramite proprietà, WizardStepse gestori eventi. In questa sezione verrà illustrato come personalizzare l'aspetto del controllo tramite le relative proprietà; La sezione successiva esamina il comportamento del controllo tramite i gestori eventi.

Praticamente tutto il testo visualizzato nell'interfaccia utente predefinita del controllo CreateUserWizard può essere personalizzato tramite la sua pletora di proprietà. Ad esempio, le etichette "User Name", "Password", "Confirm Password", "E-mail", "Security Question" e "Security Answer" visualizzate a sinistra delle caselle di testo possono essere personalizzate rispettivamente dalle UserNameLabelTextproprietà , PasswordLabelText, ConfirmPasswordLabelText, EmailLabelTextQuestionLabelText, e AnswerLabelText . Analogamente, sono disponibili proprietà per specificare il testo per i pulsanti "Crea utente" e "Continua" in CreateUserWizardStep e CompleteWizardStep, nonché se questi pulsanti vengono visualizzati come Pulsanti, LinkButton o ImageButtons.

I colori, i bordi, i tipi di carattere e altri elementi visivi sono configurabili tramite una serie di proprietà di stile. Il controllo CreateUserWizard ha le proprietà comuni dello stile del controllo Web, BackColor, BorderStyle, CssClassFonte così via, e sono disponibili numerose proprietà di stile per definire l'aspetto per sezioni specifiche dell'interfaccia di CreateUserWizard. La TextBoxStyle proprietà, ad esempio, definisce gli stili per le caselle di testo in CreateUserWizardStep, mentre la TitleTextStyle proprietà definisce lo stile per il titolo ("Iscrizione per il nuovo account").

Oltre alle proprietà correlate all'aspetto, esistono diverse proprietà che influiscono sul comportamento del controllo CreateUserWizard. La DisplayCancelButton proprietà, se impostata su True, visualizza un pulsante Annulla accanto al pulsante "Crea utente" (il valore predefinito è False). Se si visualizza il pulsante Annulla, assicurarsi di impostare anche la CancelDestinationPageUrl proprietà , che specifica la pagina a cui l'utente viene inviato dopo aver fatto clic su Annulla. Come indicato nella sezione precedente, il pulsante Continua nell'interfaccia CompleteWizardStepdell'interfaccia genera un postback, ma lascia il visitatore nella stessa pagina. Per inviare il visitatore ad un'altra pagina dopo aver fatto clic sul pulsante Continua, è sufficiente specificare l'URL nella ContinueDestinationPageUrl proprietà .

Aggiorniamo il RegisterUser controllo CreateUserWizard per visualizzare un pulsante Annulla e inviare il visitatore a Default.aspx quando si fa clic sui pulsanti Annulla o Continua. A tale scopo, impostare la DisplayCancelButton proprietà su True e entrambe le CancelDestinationPageUrl proprietà e ContinueDestinationPageUrl su "~/Default.aspx". La figura 14 mostra l'aggiornamento di CreateUserWizard quando visualizzato tramite un browser.

CreateUserWizardStep include un pulsante Annulla

Figura 14: Il CreateUserWizardStep pulsante Include un pulsante Annulla (fare clic per visualizzare l'immagine a dimensione intera)

Quando un visitatore immette un nome utente, una password, un indirizzo di posta elettronica e una domanda di sicurezza e una risposta e fa clic su "Crea utente", viene creato un nuovo account utente e il visitatore viene connesso come utente appena creato. Supponendo che la persona che visita la pagina crei un nuovo account per se stessi, è probabile che questo sia il comportamento desiderato. Tuttavia, è possibile consentire agli amministratori di aggiungere nuovi account utente. In questo modo, verrà creato l'account utente, ma l'amministratore rimarrà connesso come amministratore (e non come account appena creato). Questo comportamento può essere modificato tramite la proprietà booleanaLoginCreatedUser.

Gli account utente nel framework di appartenenza contengono un flag approvato; gli utenti che non sono approvati non sono in grado di accedere al sito. Per impostazione predefinita, un account appena creato viene contrassegnato come approvato, consentendo all'utente di accedere immediatamente al sito. È tuttavia possibile che i nuovi account utente siano contrassegnati come non approvati. Forse si vuole che un amministratore approvi manualmente nuovi utenti prima di poter accedere; o si desidera verificare che l'indirizzo di posta elettronica immesso all'iscrizione sia valido prima di consentire a un utente di accedere. Indipendentemente dal caso, è possibile che l'account utente appena creato sia contrassegnato come non approvato impostando la proprietà del DisableCreatedUser controllo CreateUserWizard su True (il valore predefinito è False).

Altre proprietà correlate al comportamento della nota includono AutoGeneratePassword e MailDefinition. Se la AutoGeneratePassword proprietà è impostata su True, non CreateUserWizardStep vengono visualizzate le caselle di testo "Password" e "Conferma password", ma la password dell'utente appena creato viene generata automaticamente usando il Membership metodo della GeneratePasswordclasse. Il GeneratePassword metodo costruisce una password di una lunghezza specificata e con un numero sufficiente di caratteri non alfanumerici per soddisfare i requisiti di complessità della password configurati.

La MailDefinition proprietà è utile se si desidera inviare un messaggio di posta elettronica all'indirizzo di posta elettronica specificato durante il processo di creazione dell'account. La MailDefinition proprietà include una serie di proprietà secondarie per la definizione di informazioni sul messaggio di posta elettronica costruito. Queste sottoproprietà includono opzioni come Subject, Priority, IsBodyHtml, FromCCe BodyFileName. La BodyFileName proprietà punta a un file HTML o di testo contenente il corpo del messaggio di posta elettronica. Il corpo supporta due segnaposto predefiniti: <%UserName%> e <%Password%>. Questi segnaposto, se presenti nel BodyFileName file, verranno sostituiti con il nome e la password dell'utente appena creati.

Nota

La CreateUserWizard proprietà del MailDefinition controllo specifica solo i dettagli relativi al messaggio di posta elettronica inviato quando viene creato un nuovo account. Non include informazioni dettagliate sul modo in cui viene effettivamente inviato il messaggio di posta elettronica , ovvero se viene usato un server SMTP o una directory di rilascio della posta elettronica, eventuali informazioni di autenticazione e così via. Questi dettagli di basso livello devono essere definiti nella <system.net> sezione di Web.config. Per altre informazioni su queste impostazioni di configurazione e sull'invio di messaggi di posta elettronica da ASP.NET 2.0 in generale, vedere le domande frequenti su SystemNetMail.com e il mio articolo, Invio di Email in ASP.NET 2.0.

Estensione del comportamento di CreateUserWizard tramite gestori eventi

Il controllo CreateUserWizard genera un numero di eventi durante il flusso di lavoro. Ad esempio, dopo che un visitatore immette il nome utente, la password e altre informazioni pertinenti e fa clic sul pulsante "Crea utente", il controllo CreateUserWizard genera l'eventoCreatingUser. Se si verifica un problema durante il processo di creazione, l'eventoCreateUserError viene generato, ma se l'utente viene creato correttamente, viene generato l'eventoCreatedUser. Sono disponibili altri eventi di controllo CreateUserWizard generati, ma questi sono i tre più tedeschi.

In alcuni scenari potrebbe essere necessario accedere al flusso di lavoro CreateUserWizard, che è possibile eseguire creando un gestore eventi per l'evento appropriato. Per illustrare questo problema, è possibile migliorare il RegisterUser controllo CreateUserWizard per includere una convalida personalizzata sul nome utente e sulla password. In particolare, è possibile migliorare createUserWizard in modo che i nomi utente non possano contenere spazi iniziali o finali e che il nome utente non venga visualizzato in nessun punto della password. In breve, si vuole impedire a qualcuno di creare un nome utente come "Scott" o avere una combinazione nome utente/password come "Scott" e "Scott.1234".

A tale scopo, verrà creato un gestore eventi per l'evento CreatingUser per eseguire i controlli di convalida aggiuntivi. Se i dati forniti non sono validi, è necessario annullare il processo di creazione. È anche necessario aggiungere un controllo Web Etichetta alla pagina per visualizzare un messaggio che spiega che il nome utente o la password non è valido. Per iniziare, aggiungere un controllo Label sotto il controllo CreateUserWizard, impostandone la ID proprietà su InvalidUserNameOrPasswordMessage e la relativa ForeColor proprietà su Red. Cancellare la proprietà Text e impostarne EnableViewState le proprietà e Visible su False.

<asp:Label runat="server" id="InvalidUserNameOrPasswordMessage"
     Visible="false" ForeColor="Red" EnableViewState="false">

</asp:Label>

Creare quindi un gestore eventi per l'evento del CreatingUser controllo CreateUserWizard. Per creare un gestore eventi, selezionare il controllo nel Designer e quindi passare al Finestra Proprietà. Fare clic sull'icona a forma di fulmine e quindi fare doppio clic sull'evento appropriato per creare il gestore eventi.

Aggiungere il codice seguente al gestore eventi CreatingUser :

protected void RegisterUser_CreatingUser(object sender, LoginCancelEventArgs e)
{
     string trimmedUserName = RegisterUser.UserName.Trim();
     if (RegisterUser.UserName.Length != trimmedUserName.Length)
     {
          // Show the error message
          InvalidUserNameOrPasswordMessage.Text = "The username cannot contain leading or trailing spaces.";
          InvalidUserNameOrPasswordMessage.Visible = true;

          // Cancel the create user workflow
          e.Cancel = true;
     }
     else
     {
          // Username is valid, make sure that the password does not contain the username

          if (RegisterUser.Password.IndexOf(RegisterUser.UserName, StringComparison.OrdinalIgnoreCase) >= 0)
          {
               // Show the error message
               InvalidUserNameOrPasswordMessage.Text = "The username may not appear anywhere in the password.";
               InvalidUserNameOrPasswordMessage.Visible = true;
               // Cancel the create user workflow
               e.Cancel = true;
          }
     }
}

Si noti che il nome utente e la password immessi nel controllo CreateUserWizard sono disponibili rispettivamente tramite le relative proprietà ePassword .UserName Queste proprietà vengono usate nel gestore eventi precedente per determinare se il nome utente fornito contiene spazi iniziali o finali e se il nome utente viene trovato all'interno della password. Se una di queste condizioni viene soddisfatta, viene visualizzato un messaggio di errore nella InvalidUserNameOrPasswordMessage proprietà Label e la proprietà del e.Cancel gestore eventi è impostata su true. Se e.Cancel è impostato su true, createUserWizard esegue il corto circuito del flusso di lavoro, annullando in modo efficace il processo di creazione dell'account utente.

La figura 15 mostra una schermata di CreatingUserAccounts.aspx quando l'utente immette un nome utente con spazi iniziali.

I nomi utente con spazi iniziali o finali non sono consentiti

Figura 15: I nomi utente con spazi iniziali o finali non sono consentiti (fare clic per visualizzare l'immagine a dimensione intera)

Nota

Nell'esercitazione Archiviazione di informazioni aggiuntive sull'utente verrà illustrato un esempio di utilizzo dell'evento del CreatedUser controllo CreateUserWizard.

Riepilogo

Il Membership metodo della CreateUser classe crea un nuovo account utente nel framework Membership. A tale scopo, delegando la chiamata al provider di appartenenze configurato. Nel caso di SqlMembershipProvider, il CreateUser metodo aggiunge un record alle tabelle di aspnet_Users database e aspnet_Membership .

Anche se è possibile creare nuovi account utente a livello di codice (come illustrato nel passaggio 5), un approccio più rapido e semplice consiste nell'usare il controllo CreateUserWizard. Questo controllo esegue il rendering di un'interfaccia utente in più passaggi per la raccolta di informazioni utente e la creazione di un nuovo utente nel framework di appartenenza. Sotto le quinte, questo controllo usa lo stesso Membership.CreateUser metodo esaminato nel passaggio 5, ma il controllo crea l'interfaccia utente, i controlli di convalida e risponde agli errori di creazione dell'account utente senza dover scrivere un'operazione di codice.

A questo punto è disponibile la funzionalità per creare nuovi account utente. Tuttavia, la pagina di accesso continua a convalidare le credenziali hardcoded specificate nella seconda esercitazione. Nell'esercitazione successiva si aggiornerà Login.aspx per convalidare le credenziali fornite dall'utente in base al framework di appartenenza.

Buon programmatori!

Altre informazioni

Per altre informazioni sugli argomenti descritti in questa esercitazione, vedere le risorse seguenti:

Informazioni sull'autore

Scott Mitchell, autore di più libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, lavora con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2.0 in 24 ore. Scott può essere raggiunto all'indirizzo mitchell@4guysfromrolla.com o tramite il suo blog all'indirizzo http://ScottOnWriting.NET.

Grazie speciale...

Questa serie di esercitazioni è stata esaminata da molti revisori utili. Il revisore principale di questa esercitazione era Teresa Murphy. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, rilasciami una riga in mitchell@4GuysFromRolla.com.