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 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 ) 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, 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:
- 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'elementomode
suForms
. 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. - 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 delloaspnet_regsql.exe
strumento per eseguire questa operazione. - 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 ilLocalSqlServer
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.
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
.
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.
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.
Aggiunta di un elenco di collegamenti Two-Level nella colonna 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, 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 .
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
.
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 FormsIdentity
CustomIdentity
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 CreateUser
classe. 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:
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 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 cuiTextMode
proprietà è impostata suPassword
- Casella di testo denominata
Email
- Etichetta denominata
SecurityQuestion
con la relativaText
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 relativaText
proprietà deselezionata
A questo punto la schermata dovrebbe essere simile alla schermata visualizzata nella figura 6.
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 CreateAccountButton
e 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 CreateUser
MembershipCreateStatus
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.
CreateUser
Dopo 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).
Figura 7: Viene creato correttamente un nuovo account utente (fare clic per visualizzare l'immagine full-size)
Figura 8: l'account utente non viene creato perché la password specificata è troppo debole (fare clic per visualizzare l'immagine a dimensioni complete)
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.
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, , 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 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.
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 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 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.
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 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à" 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à, WizardSteps
e 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 UserNameLabelText
proprietà , PasswordLabelText
, ConfirmPasswordLabelText
, EmailLabelText
QuestionLabelText
, 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 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 CompleteWizardStep
dell'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.
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 GeneratePassword
classe. 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
, From
CC
e 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.
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:
CreateUser
Documentazione tecnica- Cenni preliminari sul controllo CreateUserWizard
- Creazione di un provider di mapping del sito System-Based file
- Creazione di un'interfaccia utente dettagliata con il controllo della procedura guidata ASP.NET 2.0
- Esame della struttura di spostamento del sito di ASP.NET 2.0
- Pagine master e navigazione 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, 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.
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per