Recupero e modifica delle password (C#)

di Scott Mitchell

Nota

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

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

ASP.NET include due controlli Web per assistenza per il ripristino e la modifica delle password. Il controllo PasswordRecovery consente a un visitatore di recuperare la password persa. Il controllo ChangePassword consente all'utente di aggiornare la password. Come gli altri controlli Web correlati all'accesso illustrati in questa serie di esercitazioni, i controlli PasswordRecovery e ChangePassword funzionano con il framework di appartenenza dietro le quinte per reimpostare o modificare le password degli utenti.

Introduzione

Tra i siti Web per la mia banca, l'azienda di utilità, l'azienda telefonica, gli account di posta elettronica e i portali Web personalizzati, io, come la maggior parte delle persone, hanno decine di password diverse da ricordare. Con tante credenziali da memorizzare questi giorni, non è raro che le persone dimenticano la password. Per tenere conto di questo, i siti Web che offrono account utente devono includere un modo per un utente di recuperare la password. Questo processo comporta in genere la generazione di una nuova password casuale e la posta elettronica all'indirizzo di posta elettronica dell'utente nel file. Dopo aver ricevuto la nuova password, la maggior parte degli utenti torna al sito e modifica la password da quella generata in modo casuale a una più memorabile.

ASP.NET include due controlli Web per assistenza per il ripristino e la modifica delle password. Il controllo PasswordRecovery consente a un visitatore di recuperare la password persa. Il controllo ChangePassword consente all'utente di aggiornare la password. Come gli altri controlli Web correlati all'accesso illustrati in questa serie di esercitazioni, i controlli PasswordRecovery e ChangePassword funzionano con il framework di appartenenza dietro le quinte per reimpostare o modificare le password degli utenti.

In questa esercitazione verranno esaminati questi due controlli. Verrà anche illustrato come modificare e reimpostare a livello di codice la password di un utente tramite i metodi e ResetPassword della MembershipUser classeChangePassword.

Passaggio 1: Aiutare gli utenti a recuperare password perse

Tutti i siti Web che supportano gli account utente devono fornire agli utenti un meccanismo per il recupero delle password dimenticate. La buona notizia è che l'implementazione di tali funzionalità in ASP.NET è una brezza grazie al controllo Web PasswordRecovery. Il controllo PasswordRecovery esegue il rendering di un'interfaccia che richiede all'utente il nome utente e, se necessario, la risposta alla domanda di sicurezza. Invia quindi messaggi di posta elettronica all'utente la password.

Nota

Poiché i messaggi di posta elettronica vengono trasmessi attraverso il cavo in testo normale, esistono rischi di sicurezza coinvolti nell'invio della password di un utente tramite posta elettronica.

Il controllo PasswordRecovery è costituito da tre visualizzazioni:

  • UserName : richiede al visitatore il nome utente. Si tratta della visualizzazione iniziale.
  • Domanda: visualizza il nome utente e la domanda di sicurezza dell'utente come testo, insieme a un controllo TextBox per l'utente per immettere la risposta alla domanda di sicurezza.
  • Operazione riuscita: visualizza un messaggio che informa l'utente che la password è stata posta elettronica.

Le visualizzazioni visualizzate e le azioni eseguite dal controllo PasswordRecovery dipendono dalle impostazioni di configurazione dell'appartenenza seguenti:

  • RequiresQuestionAndAnswer
  • EnablePasswordRetrieval
  • EnablePasswordReset

L'impostazione del RequiresQuestionAndAnswer framework di appartenenza indica se gli utenti devono specificare una domanda di sicurezza e rispondere durante la registrazione di un account. Come illustrato nell'esercitazione Creazione di account utente , se è True (impostazione predefinita), l'interfaccia di CreateUserWizard include i controlli TextBox per la domanda e la risposta del nuovo utente. Se RequiresQuestionAndAnswerRequiresQuestionAndAnswer è False, non vengono raccolte tali informazioni. Analogamente, se RequiresQuestionAndAnswer è True, il controllo PasswordRecovery visualizza la visualizzazione Domanda dopo che l'utente ha immesso il nome utente. La password viene ripristinata solo se l'utente immette la risposta di sicurezza corretta. Se RequiresQuestionAndAnswer è False, tuttavia, il controllo PasswordRecovery passa direttamente dalla visualizzazione UserName alla visualizzazione Operazione riuscita.

Dopo che l'utente ha fornito il nome utente o il nome utente e la risposta di sicurezza, se RequiresQuestionAndAnswer è True, passwordRecovery invia un messaggio di posta elettronica all'utente. Se l'opzione EnablePasswordRetrieval è impostata su True, l'utente viene inviato tramite posta elettronica alla password corrente. Se è impostato su False e EnablePasswordReset viene impostato su True, il controllo PasswordRecovery genera una nuova password casuale per l'utente e invia il messaggio di posta elettronica a questa nuova password. Se entrambi EnablePasswordRetrieval e EnablePasswordReset sono False, il controllo PasswordRecovery genera un'eccezione.

Nota

Tenere presente che le SqlMembershipProvider password degli utenti vengono archiviate in uno dei tre formati: Clear, Hashed (impostazione predefinita) o Encrypted. Il meccanismo di archiviazione usato dipende dalle impostazioni di configurazione dell'appartenenza; l'applicazione demo usa il formato password hash. Quando si usa il formato password hash, l'opzione EnablePasswordRetrieval deve essere impostata su False perché il sistema non può determinare la password effettiva dell'utente dalla versione hash archiviata nel database.

La figura 1 illustra come l'interfaccia e il comportamento di PasswordRecovery sono influenzati dalla configurazione dell'appartenenza.

L'oggetto RequiresQuestionAndAnswer, EnablePasswordRetrieval e EnablePasswordReset Influenza l'aspetto e il comportamento del controllo PasswordRecovery

Figura 1: Il RequiresQuestionAndAnswercontrollo , EnablePasswordRetrievale Influenza l'aspetto e EnablePasswordReset il comportamento del controllo PasswordRecovery (Fare clic per visualizzare l'immagine full-size)

Nota

Nell'esercitazione Creazione dello schema di appartenenza in SQL Server è stato configurato il provider di appartenenza impostando RequiresQuestionAndAnswer su True, EnablePasswordRetrieval su False e EnablePasswordReset su True.

Uso del controllo PasswordRecovery

Esaminiamo l'uso del controllo PasswordRecovery in una pagina di ASP.NET. Aprire RecoverPassword.aspx e trascinare e rilasciare un controllo PasswordRecovery dalla casella degli strumenti nella Designer; impostarne su IDRecoverPwd. Come i controlli Web Login e CreateUserWizard, le visualizzazioni del controllo PasswordRecovery eseguono il rendering di un'interfaccia composita avanzata che include Etichette, Caselle di testo, Pulsanti e controlli di convalida. È possibile personalizzare l'aspetto delle visualizzazioni tramite le proprietà dello stile del controllo o convertendo le visualizzazioni in modelli. Lascio questo come esercizio per il lettore interessato.

Quando un utente visita questa pagina, immetterà il nome utente e farà clic sul pulsante Invia. Poiché la proprietà è stata impostata su True nelle impostazioni di configurazione dell'appartenenza RequiresQuestionAndAnswer , il controllo PasswordRecovery visualizzerà quindi la visualizzazione Domanda. Dopo che l'utente immette la risposta di sicurezza corretta e fa clic su Invia, il controllo PasswordRecovery aggiornerà la password dell'utente a una password generata in modo casuale e invia questa password all'indirizzo di posta elettronica nel file. Tutto questo è stato possibile senza dover scrivere una singola riga di codice!

Prima di testare questa pagina, è necessario specificare le impostazioni di recapito della posta in Web.config. Il controllo PasswordRecovery si basa su queste impostazioni per l'invio del messaggio di posta elettronica.

La configurazione del recapito della posta viene specificata tramite l'elemento<system.net> dell'elemento<mailSettings>. Utilizzare l'elemento per indicare il metodo di recapito e l'indirizzo <smtp> From predefinito. Il markup seguente configura le impostazioni di posta elettronica per usare un server SMTP di rete denominato smtp.example.com sulla porta 25 e con credenziali nome utente/password di nome utente e password.

Nota

<system.net> è un elemento figlio dell'elemento radice <configuration> e un elemento pari a <system.web>. Pertanto, non inserire l'elemento <system.net> all'interno dell'elemento <system.web> ; invece, inserirlo allo stesso livello.

<configuration>
 ...
 <system.net>
 <mailSettings>
 <smtp deliveryMethod="Network" from="youraddress@example.com">
 <network
 host="smtp.example.com"
 userName="username"
 password="password"
 port="25" />
 </smtp>
 </mailSettings>
 </system.net>
</configuration>

Oltre all'uso di un server SMTP nella rete, è possibile specificare in alternativa una directory di ritiro in cui inviare messaggi di posta elettronica da inviare.

Dopo aver configurato le impostazioni SMTP, visitare la RecoverPassword.aspx pagina tramite un browser. Provare prima di tutto a immettere un nome utente che non esiste nell'archivio utenti. Come illustrato nella figura 2, il controllo PasswordRecovery visualizza un messaggio che indica che non è possibile accedere alle informazioni utente. Il testo del messaggio può essere personalizzato tramite la proprietà del UserNameFailureTextcontrollo.

Viene visualizzato un messaggio di errore se viene immesso un nome utente non valido

Figura 2: Viene visualizzato un messaggio di errore se viene immesso un nome utente non valido (fare clic per visualizzare l'immagine full-size)

Immettere ora un nome utente. Usare il nome utente di un account nel sistema con un indirizzo di posta elettronica a cui è possibile accedere e la cui risposta di sicurezza si conosce. Dopo aver immesso il nome utente e fare clic su Invia, il controllo PasswordRecovery visualizza la visualizzazione Domanda. Come per la visualizzazione UserName, se si immette una risposta errata, il controllo PasswordRecovery visualizza un messaggio di errore (vedere La figura 3). Utilizzare la QuestionFailureText proprietà per personalizzare questo messaggio di errore.

Viene visualizzato un messaggio di errore se l'utente immette una risposta di sicurezza non valida

Figura 3: Viene visualizzato un messaggio di errore se l'utente immette una risposta di sicurezza non valida (fare clic per visualizzare un'immagine a dimensioni complete)

Immettere infine la risposta di sicurezza corretta e fare clic su Invia. Dietro le quinte, il controllo PasswordRecovery genera una password casuale, la assegna all'account utente, invia un messaggio di posta elettronica che informa l'utente della nuova password (vedere la figura 4) e quindi visualizza la visualizzazione Esito positivo.

L'utente viene inviato un Email con la nuova password

Figura 4: l'utente viene inviato un Email con la nuova password (fare clic per visualizzare l'immagine full-size)

Personalizzazione dell'Email

Il messaggio di posta elettronica predefinito inviato dal controllo PasswordRecovery è piuttosto noioso (vedere la figura 4). Il messaggio viene inviato dall'account specificato nell'attributo <smtp> dell'elemento from con l'oggetto Password e il corpo del testo normale:

Tornare al sito e accedere usando le informazioni seguenti.

Nome utente: nome utente

Password: password

Questo messaggio può essere personalizzato a livello di codice tramite un gestore eventi per l'evento del SendingMailcontrollo PasswordRecovery o dichiarativo tramite la MailDefinition proprietà . Esaminiamo entrambe queste opzioni.

L'evento SendingMail viene attivato subito prima dell'invio del messaggio di posta elettronica ed è l'ultima possibilità di modificare a livello di codice il messaggio di posta elettronica. Quando viene generato questo evento, il gestore eventi viene passato un oggetto di tipo MailMessageEventArgs, la cui Message proprietà contiene un riferimento al messaggio di posta elettronica che sta per essere inviato.

Creare un gestore eventi per l'evento e aggiungere il codice seguente, che aggiunge webmaster@example.com a livello di codice all'elenco SendingMail CC.

protected void RecoverPwd_SendingMail(object sender, MailMessageEventArgs e)
{
    e.Message.CC.Add("webmaster@example.com");
}

Il messaggio di posta elettronica può essere configurato anche tramite mezzi dichiarativi. La proprietà di PasswordRecovery MailDefinition è un oggetto di tipo MailDefinition. La MailDefinition classe offre un host di proprietà correlate alla posta elettronica, tra cui From, PriorityIsBodyHtmlCCSubjectBodyFileNamee altri. Per iniziare, impostare la Subject proprietà su un valore più descrittivo di quello usato per impostazione predefinita ( Password), ad esempio La password è stata reimpostata...

Per personalizzare il corpo del messaggio di posta elettronica, è necessario creare un file di modello di posta elettronica separato che contiene il contenuto del corpo. Iniziare creando una nuova cartella nel sito Web denominato EmailTemplates. Aggiungere quindi un nuovo file di testo a questa cartella denominata PasswordRecovery.txt e aggiungere il contenuto seguente:

Your password has been reset, <%UserName%>!

According to our records, you have requested that your password be reset. Your new
password is: <%Password%>

If you have any questions or trouble logging on please contact a site administrator.

Thank you!

Si noti l'uso dei segnaposto <%UserName%> e <%Password%>. Il controllo PasswordRecovery sostituisce automaticamente questi due segnaposto con il nome utente dell'utente e la password recuperata prima di inviare il messaggio di posta elettronica.

Infine, puntare la MailDefinitionproprietà di 's al modello di BodyFileName posta elettronica appena creato (~/EmailTemplates/PasswordRecovery.txt).

Dopo aver apportato queste modifiche, rivedere la RecoverPassword.aspx pagina e immettere il nome utente e la risposta alla sicurezza. Si riceverà un messaggio di posta elettronica simile a quello nella figura 5. Si noti che è stato cc'd e che webmaster@example.com il soggetto e il corpo sono stati aggiornati.

L'oggetto, il corpo e l'elenco CC sono stati aggiornati

Figura 5: l'oggetto, il corpo e l'elenco CC sono stati aggiornati (fare clic per visualizzare l'immagine full-size)

Per inviare un messaggio di posta elettronica formattato HTML impostato IsBodyHtml su True (il valore predefinito è False) e aggiornare il modello di posta elettronica in modo da includere HTML.

La MailDefinition proprietà non è univoca per la classe PasswordRecovery. Come si vedrà nel passaggio 2, il controllo ChangePassword offre anche una MailDefinition proprietà. Inoltre, il controllo CreateUserWizard include tale proprietà che è possibile configurare per inviare automaticamente un messaggio di posta elettronica di benvenuto ai nuovi utenti.

Nota

Attualmente non sono presenti collegamenti nello spostamento a sinistra per raggiungere la RecoverPassword.aspx pagina. Un utente sarebbe interessato solo a visitare questa pagina se non era in grado di accedere correttamente al sito. Aggiornare quindi la Login.aspx pagina per includere un collegamento alla RecoverPassword.aspx pagina.

Reimpostazione a livello di codice della password di un utente

Quando si reimposta la password di un utente, il controllo PasswordRecovery chiama il MembershipUser metodo dell'oggettoResetPassword. Questo metodo presenta due overload:

  • ResetPassword - reimposta la password di un utente. Usare questo overload se RequiresQuestionAndAnswer è False.
  • ResetPassword(securityAnswer) - reimposta la password di un utente solo se la sicurezza fornitaAnswer è corretta. Usare questo overload se RequiresQuestionAndAnswer è True.

Entrambi gli overload restituiscono la nuova password generata in modo casuale.

Come per gli altri metodi nel framework Di appartenenza, il ResetPassword metodo delega al provider configurato. Richiama SqlMembershipProvider la aspnet_Membership_ResetPassword stored procedure, passando il nome utente dell'utente, la nuova password e la risposta della password fornita, tra gli altri campi. La stored procedure garantisce che la risposta della password corrisponda e quindi aggiorni la password dell'utente.

Un paio di note di implementazione di basso livello:

  • Un utente bloccato non può reimpostare la password. Tuttavia, un utente non approvato può. Verranno illustrati gli stati bloccati e approvati in modo più dettagliato nell'esercitazione Sblocco e approvazione degli account utente.
  • Se la risposta alla password non è corretta, il numero di tentativi di risposta password non riuscito dell'utente viene incrementato. Se un numero specificato di tentativi di risposta alla sicurezza non validi si verifica entro un intervallo di tempo specificato, l'utente viene bloccato.

Word su Come vengono generate le password casuali

Le password generate casualmente visualizzate nei messaggi di posta elettronica nelle figure 4 e 5 vengono create dal metodo della GeneratePasswordclasse Membership. Questo metodo accetta due paramters di input integer, lunghezza e numeroOfNonAlphanumericCharacters, e restituisce una stringa con almeno numeroOfNonAlphanumericCharacters numero di caratteri non alfanumerici. Quando questo metodo viene chiamato dall'interno delle classi Membership o dai controlli Web correlati all'account di accesso, i valori per questi due parametri sono determinati rispettivamente dalle proprietà e della MinRequiredPasswordLength configurazione dell'appartenenza, impostate rispettivamente su 7 e MinRequiredNonalphanumericCharacters 1.

Il GeneratePassword metodo usa un generatore di numeri casuali con crittografia avanzata per garantire che non vi sia alcun pregiudizio in quali caratteri casuali sono selezionati. Inoltre, è public, GeneratePassword significa che è possibile usarlo direttamente dall'applicazione ASP.NET se è necessario generare stringhe o password casuali.

Nota

La SqlMembershipProvider classe genera sempre una password casuale di almeno 14 caratteri, quindi se MinRequiredPasswordLength è minore di 14, il valore viene ignorato.

Passaggio 2: Modifica delle password

Le password generate in modo casuale sono difficili da ricordare. Considerare la password illustrata nella figura 4: WWGUZv(f2yM:Bd. Provare a eseguire il commit in memoria! Senza bisogno di dire, dopo che un utente viene inviato una password generata in modo casuale di questo tipo, vuole modificare la password in un elemento più memorabile.

Usare il controllo ChangePassword per creare un'interfaccia per modificare la password da parte di un utente. Analogamente al controllo PasswordRecovery, il controllo ChangePassword è costituito da due visualizzazioni: Modifica password e esito positivo. La visualizzazione Modifica password richiede all'utente di specificare le password precedenti e nuove. Quando si specifica la password precedente corretta e una nuova password che soddisfa i requisiti minimi di lunghezza e carattere non alfanumerico, il controllo ChangePassword aggiorna la password dell'utente e visualizza la visualizzazione Esito positivo.

Nota

Il controllo ChangePassword modifica la password dell'utente richiamando il MembershipUser metodo dell'oggettoChangePassword. Il metodo ChangePassword accetta due string parametri di input, oldPassword e newPassword, e aggiorna l'account dell'utente con il nuovoPassword, presupponendo che l'elemento oldPassword fornito sia corretto.

Aprire la ChangePassword.aspx pagina e aggiungere un controllo ChangePassword alla pagina, denominandolo ChangePwd. A questo punto, la visualizzazione Progettazione deve visualizzare la visualizzazione Modifica password (vedere la figura 6). Come con il controllo PasswordRecovery, è possibile attivare l'interruttore tra le visualizzazioni tramite smart tag del controllo. Inoltre, queste visualizzazioni sono personalizzabili tramite le proprietà dello stile assortito o convertendole in un modello.

Aggiungere un controllo ChangePassword alla pagina

Figura 6: Aggiungere un controllo ChangePassword alla pagina (fare clic per visualizzare l'immagine a dimensioni complete)

Il controllo ChangePassword può aggiornare la password dell'utente attualmente registrata o la password di un altro utente specificato. Come illustrato nella figura 6, la visualizzazione Modifica password predefinita esegue il rendering di soli tre controlli TextBox: uno per la password precedente e due per la nuova password. Questa interfaccia predefinita viene usata per aggiornare la password dell'utente attualmente connesso.

Per usare il controllo ChangePassword per aggiornare la password di un altro utente, impostare la proprietà del DisplayUserName controllo su True. In questo modo viene aggiunto un quarto controllo TextBox alla pagina, richiedendo il nome utente dell'utente la cui password viene modificata.

L'impostazione DisplayUserName su True è utile se si vuole consentire a un utente disconnesso di modificare la password senza dover accedere. Personalmente, penso che non ci sia nulla di sbagliato con la richiesta di accesso di un utente prima di consentire a lei di modificare la password. Lasciare DisplayUserName quindi impostata su False (impostazione predefinita). Nel prendere questa decisione, tuttavia, si impedisce essenzialmente agli utenti anonimi di raggiungere questa pagina. Aggiornare le regole di autorizzazione URL del sito in modo da impedire agli utenti anonimi di visitare ChangePassword.aspx. Se è necessario aggiornare la memoria nella sintassi della regola di autorizzazione URL, fare riferimento all'esercitazione Sull'autorizzazione basata sull'utente.

Nota

Potrebbe sembrare che la DisplayUserName proprietà sia utile per consentire agli amministratori di modificare le password degli altri utenti. Tuttavia, anche quando DisplayUserName è impostato su True la password precedente corretta deve essere nota e immessa. Verranno illustrate le tecniche per consentire agli amministratori di modificare le password degli utenti nel passaggio 3.

Visitare la pagina tramite un browser e modificare la ChangePassword.aspx password. Si noti che viene visualizzato un messaggio di errore se si immette una nuova password che non soddisfa i requisiti di lunghezza della password e caratteri non alfanumerici specificati nella configurazione dell'appartenenza (vedere la figura 7).

Viene visualizzato un messaggio di errore se si immette una nuova password che non soddisfa i requisiti di lunghezza della password e caratteri non alfanumerici.

Figura 7: Aggiungere un controllo ChangePassword alla pagina (fare clic per visualizzare l'immagine full-size)

Dopo aver immesso la password precedente corretta e una nuova password valida, la password dell'utente connesso viene modificata e viene visualizzata la visualizzazione Esito positivo.

Invio di un Email di conferma

Per impostazione predefinita, il controllo ChangePassword non invia un messaggio di posta elettronica all'utente la cui password è stata appena aggiornata. Se si vuole inviare un messaggio di posta elettronica, è sufficiente configurare la proprietà del MailDefinition controllo. Verrà configurato il controllo ChangePassword in modo che l'utente venga inviato un messaggio di posta elettronica formattato html contenente la nuova password.

Iniziare creando un nuovo file nella EmailTemplates cartella denominata ChangePassword.htm. Aggiungere il markup seguente:

<html>
 <body>
 <h2>Your Password Has Been Changed!</h2>
 <p>
 This email confirms that your password has been changed.
 </p>
 <p>
 To log on to the site, use the following credentials:
 </p>
 <table>
 <tr>
 <td>
 <b>Username:</b>
 </td>
 <td>
 <%UserName%>
 </td>
 </tr>
 <tr>
 <td>
 <b>Password:</b>
 </td>
 <td>
 <%Password%>
 </td>
 </tr>
 </table>
 <p>
 If you have any questions or encounter any problems logging in,
 please contact a site administrator.
 </p>
 </body>
</html>

Impostare quindi le proprietà , e Subject della proprietà del IsBodyHtmlMailDefinitionBodyFileNamecontrollo ChangePassword su ~/EmailTemplates/ChangePassword.htm, True e La password è stata modificata rispettivamente.

Dopo aver apportato queste modifiche, rivedere la pagina e modificare nuovamente la password. Questa volta, il controllo ChangePassword invia un messaggio di posta elettronica personalizzato in formato HTML all'indirizzo di posta elettronica dell'utente nel file (vedere la figura 8).

Un messaggio di Email informa l'utente che la password è stata modificata

Figura 8: Un messaggio di Email informa l'utente che la password è stata modificata (fare clic per visualizzare l'immagine a dimensione intera)

Passaggio 3: Consentire agli amministratori di modificare le password degli utenti

Una funzionalità comune nelle applicazioni che supportano gli account utente è la possibilità per un utente amministratore di modificare le password di altri utenti. A volte questa funzionalità è necessaria perché il sistema non ha la possibilità per gli utenti di modificare le proprie password. In questo caso, l'unico modo per recuperare la password dimenticata da un utente consiste nell'assegnare una nuova password all'amministratore. Con i controlli PasswordRecovery e ChangePassword, tuttavia, gli utenti amministratori non devono occuparsi di modificare le password degli utenti, perché gli utenti sono in grado di eseguire questa operazione.

Ma cosa succede se il client insiste sul fatto che gli utenti amministratori devono essere in grado di modificare le password di altri utenti? Purtroppo, l'aggiunta di questa funzionalità può essere un po 'di lavoro. Per modificare la password di un utente, è necessario fornire la password precedente e nuova al MembershipUser metodo dell'oggetto ChangePassword , ma un amministratore non deve conoscere la password di un utente per modificarla.

Una soluzione alternativa consiste nel reimpostare prima la password dell'utente e quindi modificarla nella nuova password usando codice simile al seguente:

MembershipUser usr = Membership.GetUser(username);
string resetPwd = usr.ResetPassword();
usr.ChangePassword(resetPwd, newPassword);

Questo codice inizia recuperando informazioni sul nome utente, ovvero l'utente la cui password l'amministratore desidera modificare. Viene quindi richiamato il ResetPassword metodo , che assegna e l'utente una nuova password casuale. Questa password generata in modo casuale viene restituita dal metodo e archiviata nella variabile resetPwd. Ora che si conosce la password dell'utente, è possibile modificarla tramite una chiamata a ChangePassword.

Il problema è che questo codice funziona solo se la configurazione del sistema di appartenenza è impostata in modo che RequiresQuestionAndAnswer sia False. Se RequiresQuestionAndAnswer è True, come accade con l'applicazione, il ResetPassword metodo deve essere passato alla risposta di sicurezza. In caso contrario, genererà un'eccezione.

Se il framework di appartenenza è configurato per richiedere una domanda e una risposta di sicurezza, ma il client insiste che gli amministratori siano in grado di modificare le password degli utenti, sono disponibili tre opzioni:

  • Buttare le mani in aria e dire al cliente che questa è solo una cosa che non può essere fatto.
  • Impostare su RequiresQuestionAndAnswer False. Ciò comporta un'applicazione meno sicura. Si supponga che un utente nefarioso abbia ottenuto l'accesso alla posta in arrivo di un altro utente. Forse l'utente compromesso ha lasciato la scrivania per andare a pranzo e non ha bloccato la workstation, o forse ha eseguito l'accesso alla posta elettronica da un terminale pubblico e non si è disconnesso. In entrambi i casi, l'utente nefarioso può visitare la RecoverPassword.aspx pagina e immettere il nome utente dell'utente. Il sistema invia quindi un messaggio di posta elettronica alla password ripristinata senza richiedere la risposta di sicurezza.
  • Ignorare il livello di astrazione creato dal framework di appartenenza e lavorare direttamente con il database SQL Server. Lo schema di appartenenza include una stored procedure denominata aspnet_Membership_SetPassword che imposta la password di un utente e non richiede la risposta di sicurezza o la vecchia password per eseguire l'attività.

Nessuna di queste opzioni è particolarmente interessante, ma questo è il modo in cui la vita di uno sviluppatore va a volte.

Sono andato avanti e implementato il terzo approccio, scrivendo codice che ignora le Membership classi e MembershipUser e opera direttamente sul SecurityTutorials database.

Nota

Lavorando direttamente con il database, l'incapsulamento fornito dal framework di appartenenza è in frantumi. Questa decisione ci collega a SqlMembershipProvider, rendendo il codice meno portabile. Inoltre, questo codice potrebbe non funzionare come previsto nelle versioni future di ASP.NET se lo schema di appartenenza cambia. Questo approccio è una soluzione alternativa e, come la maggior parte delle soluzioni alternative, non è un esempio di procedure consigliate.

Il codice ha alcuni bit non attraenti ed è piuttosto lungo. Pertanto, non voglio ingombrare questo tutorial con un esame approfondito di esso. Per altre informazioni, scaricare il codice per questa esercitazione e visitare la ~/Administration/ManageUsers.aspx pagina. Questa pagina, creata nell'esercitazione precedente, elenca ogni utente. È stato aggiornato GridView per includere un collegamento alla UserInformation.aspx pagina, passando il nome utente dell'utente selezionato tramite la stringa di query. Nella UserInformation.aspx pagina vengono visualizzate informazioni sull'utente selezionato e sui caselle di testo per la modifica della password (vedere la figura 9).

Dopo aver immesso la nuova password, confermarla nel secondo controllo TextBox e fare clic sul pulsante Aggiorna utente, viene eseguito un postback e viene richiamata la aspnet_Membership_SetPassword stored procedure, aggiornando la password dell'utente. Invito i lettori interessati a questa funzionalità a acquisire familiarità con il codice e provare ad estendere la funzionalità per includere l'invio di un messaggio di posta elettronica all'utente la cui password è stata modificata.

Un amministratore può modificare la password di un utente

Figura 9: Un amministratore può modificare la password di un utente (fare clic per visualizzare l'immagine a dimensione intera)

Nota

La UserInformation.aspx pagina funziona attualmente solo se il framework di appartenenza è configurato per archiviare le password in formato Cancella o Hash. Manca il codice per crittografare la nuova password, anche se si è invitati ad aggiungere questa funzionalità. Il modo in cui è consigliabile aggiungere il codice necessario consiste nell'usare un decompiler come Reflector per esaminare il codice sorgente per i metodi in .NET Framework; iniziare esaminando il SqlMembershipProvider metodo della ChangePassword classe. Questa è la tecnica usata per scrivere il codice per creare un hash della password.

Riepilogo

ASP.NET offre due controlli che consentono agli utenti di gestire la password. Il controllo PasswordRecovery è utile per coloro che hanno dimenticato le password. A seconda della configurazione del framework di appartenenza, l'utente invia tramite posta elettronica la password esistente o una nuova password generata in modo casuale. Il controllo ChangePassword consente a un utente di aggiornare la password.

Analogamente ai controlli Login e CreateUserWizard, i controlli PasswordRecovery e ChangePassword eseguono il rendering di un'interfaccia utente avanzata senza dover scrivere un tocco di markup dichiarativo o riga di codice. Se l'interfaccia utente predefinita non soddisfa le proprie esigenze, è possibile personalizzarla tramite un'ampia gamma di proprietà di stile. In alternativa, le interfacce dei controlli possono essere convertite in modelli, per un grado di controllo ancora più fine. In background questi controlli usano l'API Membership, richiamando i MembershipUser metodi e ChangePassword dell'oggettoResetPassword.

Buon programmatori!

Altre informazioni

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

Informazioni sull'autore

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

Grazie speciale a

Questa serie di esercitazioni è stata esaminata da molti revisori utili. I revisori potenziali per questa esercitazione includono Michael Emmings e Suchi Banerjee. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com