Creazione di account utente (C#)
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 ASP.NET Identity Platform anziché i provider di appartenenze presenti al momento della scrittura di questo articolo. ASP.NET Identity offre numerosi vantaggi rispetto al sistema di appartenenza ASP.NET, tra cui :
- Prestazioni migliori
- Estendibilità e testbilità migliorate
- Supporto per OAuth, OpenID Connect e autenticazione a due fattori
- Supporto delle identità basate sulle attestazioni
- Migliore interoperabilità con ASP.Net Core
Scaricare il codice o scaricare il PDF
In questa esercitazione si esaminerà 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 dell'applicazione in un database, che ha aggiunto le tabelle, le viste e le stored procedure necessarie per SqlMembershipProvider
e SqlRoleProvider
. Questa operazione ha creato l'infrastruttura necessaria per il resto delle esercitazioni di questa serie. In questa esercitazione si esaminerà 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.
Oltre a imparare a creare nuovi account utente, è necessario aggiornare il sito Web demo creato per la prima volta nell'esercitazione Panoramica dell'autenticazione basata su form e quindi migliorato nell'esercitazione Configurazione autenticazione basata su form 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. Global.asax
Include inoltre il codice che crea oggetti e IIdentity
personalizzati IPrincipal
per gli utenti autenticati. La pagina di accesso verrà aggiornata per convalidare le credenziali degli utenti rispetto al framework di appartenenza e rimuovere la logica dell'entità di sicurezza e dell'identità personalizzata.
È ora di iniziare.
Elenco di controllo per l'autenticazione e l'appartenenza ai moduli
Prima di iniziare a usare 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 basata su form, è necessario eseguire i passaggi seguenti prima di implementare la funzionalità Di appartenenza nell'applicazione Web:
- Abilitare l'autenticazione basata su form. Come illustrato in Panoramica dell'autenticazione basata su form, l'autenticazione basata su form è abilitata modificando e impostando
Web.config
l'attributo<authentication>
dell'elementomode
su .Forms
Con l'autenticazione basata su form abilitata, ogni richiesta in ingresso viene esaminata per un ticket di autenticazione basata su form, che, se presente, identifica il richiedente. - Aggiungere lo schema dei servizi dell'applicazione al database appropriato. Quando si usa è
SqlMembershipProvider
necessario installare lo schema dei servizi dell'applicazione 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 delloaspnet_regsql.exe
strumento per eseguire questa operazione. - Personalizzare le impostazioni dell'applicazione Web per fare riferimento al database del passaggio 2. L'esercitazione Creazione dello schema di appartenenza in SQL Server ha illustrato due modi per configurare l'applicazione Web in modo che
SqlMembershipProvider
userebbe il database selezionato nel passaggio 2: modificando ilLocalSqlServer
nome del stringa di connessione oppure aggiungendo un nuovo provider registrato all'elenco dei provider del 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 form e , è necessario eseguire questi tre passaggi prima di usare la Membership
classe o i 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 le tre successive verranno esaminate varie funzioni e funzionalità correlate all'appartenenza. Saranno necessarie una serie di pagine ASP.NET per implementare gli argomenti esaminati in queste esercitazioni. Creare queste pagine e quindi un file (Web.sitemap)
della mappa del sito.
Per iniziare, creare 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 il Esplora soluzioni del progetto dovrebbe essere simile allo screenshot illustrato nella figura 1.
Figura 1: Sono state aggiunte cinque nuove pagine alla cartella (fare clic per visualizzare l'immagine Membership
a dimensione intera)
A questo punto, ogni pagina deve avere i due controlli Contenuto, uno per ognuno dei ContentPlaceHolders 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 Content2
controllo Contenuto, tuttavia, esegue l'override del markup predefinito della pagina master. Come illustrato in Un'esercitazione Panoramica dell'autenticazione basata su form, questa opzione è utile nelle pagine in cui non si vogliono visualizzare le opzioni correlate all'accesso nella colonna a sinistra.
Per queste cinque pagine, tuttavia, si vuole mostrare il markup predefinito della pagina master per LoginContent
ContentPlaceHolder. Rimuovere quindi il markup dichiarativo per il Content2
controllo Contenuto. Dopo questa operazione, ognuno dei cinque markup della pagina 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 navigazione 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 la metà della storia. Abbiamo anche bisogno di alcuni mezzi per definire la struttura logica del sito in modo gestibile e aggiornabile. Man mano che vengono aggiunte o rimosse pagine esistenti, è possibile aggiornare una singola origine, ovvero la mappa del sito, e riflettere tali modifiche nell'interfaccia utente di navigazione 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 del sito e ai controlli Web di spostamento aggiunti in ASP.NET versione 2.0. Il framework mappa del sito consente a uno sviluppatore di definire una mappa del sito e quindi di accedervi tramite un'API programmatica (la SiteMap
classe ). I controlli Web di spostamento predefiniti includono un controllo Menu, il controllo TreeView e il controllo SiteMapPath.
Analogamente ai framework di appartenenza e ruoli, il framework mappa del sito viene creato in cima al modello di provider. Il processo della classe del provider Site Map consiste nel generare la struttura in memoria utilizzata dalla SiteMap
classe da un archivio dati permanente, ad esempio un file XML o una tabella di database. .NET Framework viene fornito con un provider predefinito di Mappa siti 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 alternative del provider della mappa del sito, vedere la sezione Ulteriori letture alla fine di questa esercitazione.
Il provider predefinito di Mapping siti prevede che esista una directory radice in un file Web.sitemap
XML formattato correttamente. Poiché si usa questo provider predefinito, è necessario aggiungere tale file 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
.
Figura 2: Aggiungere un file denominato Web.sitemap
alla directory radice del progetto (fare clic per visualizzare l'immagine a dimensione intera)
Il file di 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 con 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 <siteMapNode>
elemento deve includere un title
attributo e può includere url
facoltativamente attributi e description
, tra gli altri, ogni 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.
Figura 3: La mappa del sito rappresenta una struttura di spostamento gerarchica (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 3: Aggiornamento della pagina master per includere un'interfaccia utente di spostamento
ASP.NET include numerosi controlli Web correlati allo spostamento per la progettazione di un'interfaccia utente. Sono inclusi 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 una barra 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 tramite SiteMapDataSource e possono essere accessibili a livello di codice tramite la SiteMap
classe .
Poiché una descrizione approfondita del framework mappa del sito e dei controlli di spostamento non rientra nell'ambito di questa serie di esercitazioni, anziché dedicare tempo alla creazione di un'interfaccia utente di navigazione personalizzata, è 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 puntato a due profondità di collegamenti di spostamento, come illustrato nella figura 4.
Aggiunta di un elenco a due livelli di collegamenti nella colonna a sinistra
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, inizia a restituire la gerarchia della mappa del sito a partire dai discendenti del nodo "Home". Il Repeater visualizza ognuno di questi nodi (attualmente solo "Appartenenza") in un <li>
elemento . Un altro ripetitore interno visualizza quindi gli elementi figlio del nodo corrente in un elenco annidato non ordinato.
La figura 4 mostra l'output sottoposto a rendering del markup precedente con la struttura della mappa del sito creata nel passaggio 2. Il Repeater 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 pagine master e navigazione sito.
Figura 4: Viene eseguito il rendering dell'interfaccia utente di navigazione utilizzando elenchi annidati non ordinati (fare clic per visualizzare l'immagine a dimensione intera)
Aggiunta dello spostamento tramite navigazione
Oltre all'elenco di collegamenti nella colonna a sinistra, è anche possibile visualizzare un percorso di navigazione per ogni pagina. Un percorso di navigazione è un elemento dell'interfaccia utente di navigazione che mostra rapidamente agli utenti la 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 percorso di navigazione basato su 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 Oggetto 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
.
Figura 5: La barra di navigazione visualizza la pagina corrente e i relativi predecessori nella mappa del sito (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 4: Rimozione dell'entità di sicurezza personalizzata e della logica dell'identità
Gli oggetti entità e identità personalizzati possono essere associati all'utente autenticato. A tale scopo, è stato creato 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 FormsIdentity
aggiunti da FormsAuthenticationModule
con gli CustomPrincipal
oggetti e CustomIdentity
creati in tale esercitazione.
Sebbene gli oggetti entità e identità personalizzati siano utili in determinati scenari, nella maggior parte dei casi gli GenericPrincipal
oggetti e FormsIdentity
sono sufficienti. Di conseguenza, penso che sarebbe opportuno tornare al comportamento predefinito. Apportare questa modifica rimuovendo o commentando il PostAuthenticateRequest
gestore eventi o eliminando completamente il Global.asax
file.
Passaggio 5: Creazione di un nuovo utente a livello di codice
Per creare un nuovo account utente tramite il framework Di appartenenza, usare il Membership
metodo della CreateUser
classe. Questo metodo include parametri di input per il nome utente, la password e altri campi correlati all'utente. Alla chiamata, delega la creazione del nuovo account utente al provider di appartenenze configurato e quindi restituisce un MembershipUser
oggetto che rappresenta l'account utente appena creato.
Il CreateUser
metodo ha quattro overload, ognuno che accetta un numero diverso di parametri di input:
CreateUser(username, password)
CreateUser(username, password, email)
CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, MembershipCreateStatus)
CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, MembershipCreateStatus)
Questi quattro overload variano in base alla 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 appartenenze. Nell'esercitazione Creazione dello schema di appartenenza in SQL Server è stata esaminata l'impostazione delle impostazioni di configurazione del provider di appartenenze in .Web.config
La tabella 2 includeva un elenco completo delle impostazioni di configurazione.
Un'impostazione di configurazione del provider di appartenenze 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 requiresQuestionAndAnswer
è impostato su true
, la chiamata di uno dei primi due CreateUser
overload genera un'eccezione perché la domanda di sicurezza e la risposta sono mancanti. Poiché l'applicazione è attualmente configurata per richiedere una domanda e una risposta di 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 , creare 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:
- Un controllo TextBox denominato
Username
- Controllo TextBox denominato
Password
, la cuiTextMode
proprietà è impostata suPassword
- Un controllo TextBox denominato
Email
- Etichetta denominata
SecurityQuestion
con la relativaText
proprietà cancellata - Un controllo TextBox denominato
SecurityAnswer
- Pulsante denominato
CreateAccountButton
la cui proprietà Text è impostata su "Crea l'account utente" - Controllo Label denominato
CreateAccountResults
con la relativaText
proprietà deselezionata
A questo punto la schermata dovrebbe essere simile alla schermata illustrata nella figura 6.
Figura 6: Aggiungere i vari controlli Web alla pagina (fare clic per visualizzare l'immagine CreatingUserAccounts.aspx
a dimensione intera)
Label SecurityQuestion
e SecurityAnswer
TextBox sono progettati per 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 in base all'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
, assegnando 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 CreateAccountButton
di Click
e 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
. D'altra parte, 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 CreateUser
MembershipCreateStatus
nel metodo come out
parametro. Questo parametro è impostato sul valore appropriato all'interno del CreateUser
metodo ed è possibile esaminarne il valore dopo la chiamata al metodo per determinare se l'account utente è stato creato correttamente.
Dopo aver chiamato CreateUser
, 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 un nuovo utente è stato creato correttamente. 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 complessità della password specificati nelle impostazioni di configurazione del provider di appartenenze. Nella figura 9 il visitatore sta tentando di creare un account utente con un nome utente esistente (quello creato nella figura 7).
Figura 7: Creazione di un nuovo account utente (fare clic per visualizzare l'immagine a dimensione intera)
Figura 8: L'account utente non viene creato perché la password specificata è troppo debole (fare clic per visualizzare l'immagine a dimensione intera)
Figura 9: L'account utente non viene creato perché il nome utente è già in uso (fare clic per visualizzare l'immagine a dimensione intera)
Nota
Ci si potrebbe chiedere come determinare l'esito positivo o negativo 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'eccezione MembershipCreateUserException
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.
Figura 10: Ci sono due utenti nell'Archivio utenti di appartenenza: Tito e Bruce (Fare clic per visualizzare l'immagine a dimensione intera)
Mentre l'archivio utenti di appartenenza include ora le informazioni sull'account di Bruce e Tito, dobbiamo ancora implementare funzionalità che consentono 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 il momento, la visualizzazione dei nuovi account utente nelle aspnet_Users
tabelle e aspnet_Membership
dovrà essere sufficiente. Nell'esercitazione successiva, convalida delle credenziali utente rispetto all'archivio utenti di appartenenza, aggiorneremo la pagina di accesso per convalidare l'archivio appartenenze.
Nota
Se non vengono visualizzati utenti nel SecurityTutorials.mdf
database, è possibile che l'applicazione Web usi il provider di appartenenza predefinito, AspNetSqlMembershipProvider
, che 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 denominato ASPNETDB.mdf
, si tratta del problema. Tornare al passaggio 4 dell'esercitazione Creazione dello schema di appartenenza in SQL Server per istruzioni su come configurare correttamente il provider di appartenenze.
Nella maggior parte degli scenari di creazione dell'account utente, il visitatore viene presentato con un'interfaccia per immettere il nome utente, la password, la posta elettronica e altre informazioni essenziali, a questo punto viene creato un nuovo account. In questo passaggio è stato esaminato come creare un'interfaccia di questo tipo a mano e quindi si è visto come usare il Membership.CreateUser
metodo per aggiungere il nuovo account utente a livello di codice in base agli input dell'utente. Il codice, tuttavia, ha appena creato il nuovo account utente. Non ha eseguito alcuna azione di completamento, ad esempio l'accesso dell'utente al sito con l'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 è 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 Crea account, è improbabile che sia necessario scrivere codice che usi il CreateUser
metodo, perché il controllo CreateUserWizard probabilmente soddisfa le proprie esigenze. Tuttavia, il CreateUser
metodo è utile negli scenari in cui è necessaria un'esperienza utente di creazione 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 informazioni utente da un'altra applicazione. La pagina può 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 facilitano molti scenari comuni relativi all'account utente e all'account di 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 degli 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 generati 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, il controllo può essere convertito in un modello o è possibile aggiungere "passaggi" di registrazione utente aggiuntivi.
Si inizierà con un'analisi dell'interfaccia e del 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 Divisione 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, la 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 del nuovo utente.
Figura 11: Il controllo CreateUserWizard esegue il rendering di un'interfaccia utente di creazione generica (fare clic per visualizzare l'immagine a dimensione intera)
Diamo un po' di tempo per 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
è impostata su True. Analogamente, CreateUserWizard aggiunge automaticamente un controllo RegularExpressionValidator per assicurarsi che i requisiti di complessità della password siano soddisfatti e ne imposta ErrorMessage
le proprietà e ValidationExpression
in base alle minRequiredPasswordLength
impostazioni di configurazione , minRequiredNonalphanumericCharacters
e 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 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
: esegue il rendering di 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 utente aggiuntive.
Vediamo 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 non complessa insufficienti.
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, create create un nuovo account utente tramite il framework di appartenenza e quindi visualizzare l'interfaccia della password (vedere la CompleteWizardStep
figura 13). Dietro le quinte, CreateUserWizard chiama il Membership.CreateUser
metodo , proprio come nel passaggio 5.
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 CompleteWizardStep
di 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à" verrà illustrato come è possibile fare in modo che questo pulsante invii il visitatore a Default.aspx
(o 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à, WizardSteps
e gestori eventi. In questa sezione verrà illustrato come personalizzare l'aspetto del controllo tramite le relative proprietà; la sezione successiva esamina l'estensione del comportamento del controllo tramite 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 "Nome utente", "Password", "Conferma password", "Posta elettronica", "Domanda di sicurezza" e "Risposta alla sicurezza" visualizzate a sinistra delle caselle di testo possono essere personalizzate rispettivamente dalle UserNameLabelText
proprietà , , PasswordLabelText
QuestionLabelText
ConfirmPasswordLabelText
EmailLabelText
, , 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
CssClass
, Font
e così via, e sono disponibili diverse proprietà di stile per definire l'aspetto per determinate sezioni 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 ("Iscriviti per il tuo 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 CompleteWizardStep
dell'interfaccia provoca un postback, ma lascia il visitatore nella stessa pagina. Per inviare il visitatore ad altre pagine dopo aver fatto clic sul pulsante Continua, è sufficiente specificare l'URL nella ContinueDestinationPageUrl
proprietà .
Aggiornare 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 le CancelDestinationPageUrl
proprietà e ContinueDestinationPageUrl
su "~/Default.aspx". La figura 14 mostra l'elemento CreateUserWizard aggiornato quando visualizzato tramite un browser.
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 stia creando un nuovo account per se stessi, questo è probabilmente il comportamento desiderato. Tuttavia, è possibile consentire agli amministratori di aggiungere nuovi account utente. In questo modo, l'account utente verrà creato, ma l'amministratore rimarrà connesso come amministratore (e non come account appena creato). Questo comportamento può essere modificato tramite la proprietà booleana.LoginCreatedUser
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 forse si vuole 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, CreateUserWizardStep
non vengono visualizzate le caselle di testo "Password" e "Conferma password", ma viene generata automaticamente la password dell'utente appena creato usando il Membership
metodo della GeneratePassword
classe. Il GeneratePassword
metodo costruisce una password di 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
, From
, CC
e BodyFileName
. La BodyFileName
proprietà punta a un file HTML o di testo che contiene 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 dettagli sul modo in cui il messaggio di posta elettronica viene effettivamente inviato ( ovvero se viene usata una directory smtp server o di rilascio della posta elettronica, eventuali informazioni di autenticazione e così via). Questi dettagli di basso livello devono essere definiti nella <system.net>
sezione in 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 all'indirizzo SystemNetMail.com e all'articolo Invio di messaggi di posta elettronica 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, viene generato l'evento, ma se l'utente viene creato correttamente, viene generato l'eventoCreatedUser
.CreateUserError
Sono disponibili altri eventi di controllo CreateUserWizard che vengono generati, ma questi sono i tre più tedeschi.
In alcuni scenari è possibile usare il 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 per il nome utente e la password. In particolare, è possibile migliorare createUserWizard in modo che i nomi utente non possano contenere spazi iniziali o finali e il nome utente non possa essere visualizzato in qualsiasi punto della password. In breve, vogliamo impedire a un utente di creare un nome utente come "Scott" o avere una combinazione di 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 indica 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 Text
proprietà 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 in Progettazione e quindi passare al Finestra Proprietà. Fare clic sull'icona del 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 UserName
proprietà e Password
. Queste proprietà vengono usate nel gestore eventi precedente per determinare se il nome utente specificato 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 nell'etichetta InvalidUserNameOrPasswordMessage
e la proprietà del e.Cancel
gestore eventi è impostata su true
. Se e.Cancel
è impostato su true
, createUserWizard corto circuito il 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.
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 i nuovi account utente possono essere creati 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 lick 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 illustrati in questa esercitazione, vedere le risorse seguenti:
CreateUser
Documentazione tecnica- Panoramica del controllo CreateUserWizard
- Creazione di un provider di mappe del sito basato su file system
- Creazione di un'interfaccia utente dettagliata con il controllo procedura guidata ASP.NET 2.0
- Esame della struttura di spostamento del sito di ASP.NET 2.0
- Pagine master e navigazione nel sito
- Provider della mappa del sito SQL in attesa
Informazioni sull'autore
Scott Mitchell, autore di più libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato 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 speciali a...
Questa serie di esercitazioni è stata esaminata da molti revisori utili. Il revisore principale per questa esercitazione era Teresa Murphy. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, rilasciarmi una riga in mitchell@4GuysFromRolla.com.