Implementazione di un provider di appartenenze

Aggiornamento: novembre 2007

L'appartenenza ASP.NET è progettata per consentire l'utilizzo di diversi provider di appartenenze per le applicazioni ASP.NET. È possibile utilizzare i provider di appartenenze forniti con .NET Framework oppure implementare provider personalizzati.

La creazione di un provider di appartenenze personalizzato è consigliata quando:

  • Le informazioni relative all'appartenenza devono essere archiviate in un'origine dati che non è supportata dai provider di appartenenze inclusi in .NET Framework, ad esempio un database FoxPro o Oracle.

  • È necessario gestire le informazioni relative all'appartenenza utilizzando uno schema di database diverso da quello utilizzato dai provider forniti con .NET Framework. Un caso tipico è rappresentato dai dati di appartenenza già esistenti in un database SQL Server per un'azienda o un sito Web.

Classi obbligatorie

Per implementare un provider di appartenenze occorre creare una classe che erediti la classe astratta MembershipProvider dallo spazio dei nomi System.Web.Security. Poiché la classe astratta MembershipProvider eredita la classe astratta ProviderBase dallo spazio dei nomi System.Configuration.Provider, è necessario implementare anche i membri richiesti della classe ProviderBase. Nelle tabelle riportate di seguito sono elencate le proprietà e i metodi che devono essere implementati dalle classi astratte ProviderBase e MembershipProvider, unitamente alla relativa descrizione. Per la procedura di implementazione di ciascun membro, vedere il codice fornito per l'argomento Implementazione di un provider di appartenenze di esempio.

Membri di ProviderBase obbligatori

Membro

Descrizione

Metodo Initialize

Accetta come input il nome di un provider e un oggetto NameValueCollection di impostazioni di configurazione. Viene utilizzato per impostare i valori delle proprietà per l'istanza di provider, inclusi i valori specifici dell'implementazione e le opzioni specificate nel file di configurazione (Machine.config o Web.config).

Membri di MembershipProvider obbligatori

Membro

Descrizione

Proprietà EnablePasswordReset

Valore Boolean specificato nel file di configurazione (Web.config).

La proprietà EnablePasswordReset indica se gli utenti possono utilizzare il metodo ResetPassword per sovrascrivere la password corrente con una nuova password generata casualmente.

Questa proprietà è in sola lettura.

Proprietà EnablePasswordRetrieval

Valore Boolean specificato nel file di configurazione (Web.config).

La proprietà EnablePasswordRetrieval indica se gli utenti possono recuperare la password utilizzando il metodo GetPassword.

Questa proprietà è in sola lettura.

Proprietà RequiresQuestionAndAnswer

Valore Boolean specificato nel file di configurazione (Web.config).

La proprietà RequiresQuestionAndAnswer stabilisce se gli utenti devono fornire una risposta per la password prima di poter recuperare o reimpostare la password rispettivamente mediante il metodo GetPassword o il metodo ResetPassword.

Questa proprietà è in sola lettura.

Proprietà RequiresUniqueEmail

Valore Boolean specificato nel file di configurazione (Web.config).

La proprietà RequiresUniqueEmail indica se gli utenti devono fornire un indirizzo di posta elettronica univoco quando creano un utente. Se un utente esiste già nell'origine dati per la proprietà ApplicationName corrente, il metodo CreateUser restituisce un valore null (Nothing in Visual Basic) e un valore di stato DuplicateEmail.

Questa proprietà è in sola lettura.

Proprietà PasswordFormat

Valore MembershipPasswordFormat specificato nel file di configurazione (Web.config).

La proprietà PasswordFormat indica il formato di archiviazione delle password. Le password possono essere archiviate nei formati Clear, Encrypted e Hashed. Le password in formato Clear vengono archiviate come testo normale. Pur garantendo migliori prestazioni in termini di archiviazione e recupero delle password, questo formato risulta meno sicuro in quanto le password vengono lette facilmente nel caso in cui l'origine dati venga compromessa. Le password in formato Encrypted vengono crittografate al momento dell'archiviazione e possono essere decrittografate per il confronto o il recupero di password. Questo formato richiede un'elaborazione aggiuntiva per l'archiviazione e il recupero delle password, ma è più sicuro in quanto le password non vengono determinate facilmente se l'origine dati viene compromessa. Per le password in formato Hashed viene generato un hash utilizzando un algoritmo di hash a una via e un valore salt generato casualmente quando vengono archiviate nel database. Quando una password viene convalidata, viene generato un hash con il valore salt presente nel database. Non è possibile recuperare password hash.

È possibile utilizzare i metodi virtuali EncryptPassword e DecryptPassword della classe MembershipProvider per crittografare e decrittografare i valori delle password oppure fornire il proprio codice di crittografia. Se si utilizzano i metodi virtuali EncryptPassword e DecryptPassword della classe MembershipProvider, le password Encrypted vengono crittografate utilizzando le informazioni chiave fornite nella configurazione Elemento machineKey (schema delle impostazioni ASP.NET).

Questa proprietà è in sola lettura.

Proprietà MaxInvalidPasswordAttempts

Valore Integer specificato nel file di configurazione (Web.config).

La proprietà MaxInvalidPasswordAttempts interagisce con la proprietà PasswordAttemptWindow per impedire che un'origine indesiderata tenti di individuare la password o la risposta per la password di un utente di appartenenza attraverso ripetuti tentativi. Se il numero di password o di risposte per la password non valide fornite per un utente di appartenenza supera la proprietà MaxInvalidPasswordAttempts entro il numero di minuti specificato dalla proprietà PasswordAttemptWindow, l'utente di appartenenza viene bloccato mediante l'impostazione della proprietà IsLockedOut su true finché non verrà sbloccato tramite il metodo UnlockUser. Se viene fornita una password o una risposta per la password valida prima che venga raggiunto il valore della proprietà MaxInvalidPasswordAttempts, il contatore che tiene traccia del numero di tentativi non validi verrà azzerato.

Se la proprietà RequiresQuestionAndAnswer è impostata su false, i tentativi di risposta per la password non validi non vengono registrati.

Le password e i tentativi di risposta per le password non validi vengono registrati nei metodi ValidateUser, ChangePassword, ChangePasswordQuestionAndAnswer, GetPassword e ResetPassword.

Questa proprietà è in sola lettura.

Proprietà PasswordAttemptWindow

Valore Integer specificato nel file di configurazione (Web.config).

Per una descrizione, vedere la descrizione della proprietà MaxInvalidPasswordAttempts.

Questa proprietà è in sola lettura.

Proprietà ApplicationName

Il nome dell'applicazione che utilizza le informazioni relative all'appartenenza specificate nel file di configurazione (Web.config). La proprietà ApplicationName viene archiviata nell'origine dati insieme alle informazioni utente associate e utilizzata per l'esecuzione di query su tali informazioni. Per ulteriori informazioni, vedere la sezione relativa alla proprietà ApplicationName più avanti in questo argomento.

Questa proprietà è di lettura-scrittura e il valore predefinito è ApplicationPath, a meno che non venga specificata in modo esplicito.

Metodo CreateUser

Accetta come input il nome di un nuovo utente, una password e un indirizzo di posta elettronica e inserisce nell'origine dati un nuovo utente per l'applicazione. Il metodo CreateUser restituisce un oggetto MembershipUser compilato con le informazioni dell'utente appena creato. Il metodo CreateUser definisce anche un parametro out (in Visual Basic è possibile utilizzare ByRef) che restituisce un valore MembershipCreateStatus. Tale valore indica se l'utente è stato creato o il motivo per cui l'utente non è stato creato.

Il metodo CreateUser genera l'evento ValidatingPassword, se è stata specificata una proprietà MembershipValidatePasswordEventHandler, e continua l'azione di creazione dell'utente in base ai risultati dell'evento. Il metodo virtuale OnValidatingPassword può essere utilizzato per eseguire il MembershipValidatePasswordEventHandler specificato.

Metodo UpdateUser

Accetta come input un oggetto MembershipUser in cui sono inserite le informazioni utente e aggiorna l'origine dati con i valori forniti.

Metodo DeleteUser

Accetta come input il nome di un utente ed elimina le informazioni relative all'utente dall'origine dati. Il metodo DeleteUser restituisce true se l'utente è stato eliminato, altrimenti restituisce false. Un ulteriore parametro Boolean viene incluso per indicare se vengono eliminate anche informazioni relative all'utente, ad esempio informazioni sul ruolo o sul profilo.

Metodo ValidateUser

Accetta come input un nome utente e una password e verifica che i valori corrispondano a quelli presenti nell'origine dati. Il metodo ValidateUser restituisce true quando il nome utente e la password corrispondono; altrimenti restituisce false.

Metodo GetUser

Accetta come input un ID utente univoco e un valore Boolean che indica se aggiornare il valore LastActivityDate per l'utente per mostrare che l'utente è attualmente in linea. Il metodo GetUser restituisce un oggetto MembershipUser in cui sono inseriti i valori correnti dell'origine dati per l'utente specificato. Se il nome utente non viene trovato nell'origine dati, il metodo GetUser restituisce un valore null (Nothing in Visual Basic).

Metodo GetUser

Accetta come input un nome utente e un valore Boolean che indicano se aggiornare il valore LastActivityDate per l'utente per mostrare che l'utente è attualmente in linea. Il metodo GetUser restituisce un oggetto MembershipUser in cui sono inseriti i valori correnti dell'origine dati per l'utente specificato. Se il nome utente non viene trovato nell'origine dati, il metodo GetUser restituisce un valore null (Nothing in Visual Basic).

Metodo GetAllUsers

Restituisce un insieme MembershipUserCollection contenente oggetti MembershipUser per tutti gli utenti dell'origine dati.

I risultati restituiti da GetAllUsers sono limitati dai parametri pageIndex e pageSize. Il parametro pageSize identifica il numero massimo di oggetti MembershipUser da restituire in MembershipUserCollection. Il parametro pageIndex consente l'identificazione della pagina di risultati da restituire, dove 1 identifica la prima pagina. totalRecords è un parametro out impostato sul numero totale di utenti di appartenenza. Se ad esempio venissero rilevati 13 utenti nel database dell'applicazione e il valore di pageIndex fosse 2 con un valore pageSize pari a 5, l'insieme MembershipUserCollection restituito conterrebbe dal sesto al decimo utente restituito. totalRecords verrebbe impostato su 13.

Metodo GetNumberOfUsersOnline

Restituisce un numero intero che corrisponde al totale degli utenti presenti nell'origine dati dove il valore LastActivityDate è superiore alla data/ora corrente meno la proprietà UserIsOnlineTimeWindow. La proprietà UserIsOnlineTimeWindow è un valore intero che specifica il numero di minuti da utilizzare per determinare se un utente è in linea.

Metodo ResetPassword

Accetta come input un nome utente e una risposta per la password e genera una nuova password casuale per l'utente specificato. Il metodo ResetPassword aggiorna le informazioni relative all'utente nell'origine dati con la nuova password e restituisce la nuova password come una string. Un utile meccanismo per la generazione di una password casuale è costituito dal metodo GeneratePassword della classe Membership.

Il metodo ResetPassword assicura che la proprietà EnablePasswordReset sia impostata su true prima di eseguire qualsiasi azione. Se la proprietà EnablePasswordReset è false, verrà generata un'eccezione NotSupportedException. Il metodo ResetPassword verifica anche il valore della proprietà RequiresQuestionAndAnswer. Se questa proprietà è impostata su true, il metodo ResetPassword confronta il valore del parametro di risposta fornito con la risposta archiviata nell'origine dati. Se i valori non corrispondono, verrà generata un'eccezione MembershipPasswordException.

Se è stata specificata una proprietà MembershipValidatePasswordEventHandler il metodo ResetPassword genera l'evento ValidatingPassword per convalidare la password generata, quindi continua o annulla la reimpostazione della password in base ai risultati dell'evento. Il metodo virtuale OnValidatingPassword può essere utilizzato per eseguire il MembershipValidatePasswordEventHandler specificato.

Metodo GetPassword

Accetta come input un nome utente e una risposta per la password, recupera la password per l'utente specifico dall'origine dati, quindi restituisce la password come una string.

Il metodo GetPassword assicura che la proprietà EnablePasswordRetrieval sia impostata su true prima di eseguire qualsiasi azione. Se la proprietà EnablePasswordRetrieval è false, verrà generata un'eccezione ProviderException.

Il metodo GetPassword verifica anche il valore della proprietà RequiresQuestionAndAnswer. Se questa proprietà è impostata su true, il metodo GetPassword confronta il valore del parametro di risposta fornito con la risposta archiviata nell'origine dati. Se i valori non corrispondono, verrà generata un'eccezione MembershipPasswordException.

Metodo GetUserNameByEmail

Accetta come input un indirizzo di posta elettronica e restituisce il primo nome utente incluso nell'origine dati in cui l'indirizzo corrisponde al valore del parametro email fornito.

Se non viene trovato alcun nome utente con un indirizzo di posta elettronica corrispondente, verrà restituita una stringa vuota.

Se vengono trovati più nomi utente che corrispondono a un determinato indirizzo di posta elettronica, verrà restituito solo il primo nome utente rilevato.

Metodo ChangePassword

Accetta come input un nome utente, una password corrente e una nuova password, quindi aggiorna la password nell'origine dati se il nome utente e la password corrente specificati sono validi. Il metodo ChangePassword restituisce true se la password è stata aggiornata, altrimenti restituisce false.

Il metodo ChangePassword genera l'evento ValidatingPassword, se è stata specificata una proprietà MembershipValidatePasswordEventHandler, e continua o annulla l'azione di modifica della password in base ai risultati dell'evento. Il metodo virtuale OnValidatingPassword può essere utilizzato per eseguire il MembershipValidatePasswordEventHandler specificato.

Metodo ChangePasswordQuestionAndAnswer

Accetta come input un nome utente, una password, una domanda e una risposta per la password e aggiorna la domanda e la risposta alla password nell'origine dati se il nome utente e la password specificati sono validi. Il metodo ChangePasswordQuestionAndAnswer restituisce true se la domanda e la risposta per la password vengono aggiornate, altrimenti restituisce false.

Se il nome utente e la password forniti non sono validi, verrà restituito false.

Metodo FindUsersByName

Restituisce un elenco di utenti di appartenenza nel quale il nome utente contiene un valore corrispondente al parametro usernameToMatch fornito per la proprietà ApplicationName configurata. Ad esempio, se il parametro usernameToMatch è impostato su "utente," vengono restituiti gli utenti "utente1," "utente2," "utente3" e così via. Il supporto per i caratteri jolly è incluso in base al tipo di origine dati. Gli utenti vengono restituiti in ordine alfabetico in base al nome utente.

I risultati restituiti da FindUsersByName sono limitati dai parametri pageIndex e pageSize. Il parametro pageSize identifica il numero di oggetti MembershipUser da restituire nell'insieme MembershipUserCollection. Il parametro pageIndex consente l'identificazione della pagina di risultati da restituire, dove 1 identifica la prima pagina. totalRecords è un parametro out impostato sul numero totale di utenti di appartenenza corrispondente al valore usernameToMatch. Se ad esempio venissero rilevati 13 utenti il cui parametro usernameToMatch corrisponde interamente o in parte al nome utente e il valore pageIndex è 2 con un valore pageSize pari a 5, l'insieme MembershipUserCollection conterrebbe dal sesto al decimo utente restituito. Il parametro totalRecords verrebbe impostato su 13.

Metodo FindUsersByEmail

Restituisce un elenco di utenti di appartenenza nel quale il nome utente contiene un valore corrispondente al parametro emailToMatch fornito per la proprietà ApplicationName configurata. Ad esempio, se il parametro emailToMatch è impostato su "indirizzo@esempio.com," verranno restituiti gli utenti con gli indirizzi di posta elettronica "indirizzo1@esempio.com", "indirizzo2@esempio.com" e così via Il supporto per i caratteri jolly è incluso in base al tipo di origine dati. Gli utenti vengono restituiti in ordine alfabetico in base al nome utente.

I risultati restituiti da FindUsersByEmail sono limitati dai parametri pageIndex e pageSize. Il parametro pageSize identifica il numero di oggetti MembershipUser da restituire nell'insieme MembershipUserCollection. Il parametro pageIndex consente l'identificazione della pagina di risultati da restituire, dove 1 identifica la prima pagina. totalRecords è un parametro out impostato sul numero totale di utenti di appartenenza corrispondente al valore emailToMatch. Se ad esempio venissero rilevati 13 utenti il cui parametro emailToMatch corrisponde interamente o in parte al nome utente e il valore pageIndex è 2 con un valore pageSize pari a 5, l'insieme MembershipUserCollection conterrebbe dal sesto al decimo utente restituito. Il parametro totalRecords verrebbe impostato su 13.

Metodo UnlockUser

Accetta come input un nome utente e aggiorna il campo dell'origine dati in cui la proprietà IsLockedOut viene impostata su false. Il metodo UnlockUser restituisce true se il record relativo all'utente di appartenenza è stato aggiornato, altrimenti restituisce false.

ApplicationName

I provider di appartenenze archiviano le informazioni relative agli utenti in modo univoco per ciascun applicazione. Questo consente a più applicazioni ASP.NET di utilizzare la stessa origine dati senza generare un conflitto nel caso in cui vengano creati nomi utente duplicati. In alternativa, più applicazioni ASP.NET possono utilizzare la stessa origine dati utente specificando la stessa proprietà ApplicationName.

Poiché i provider di appartenenze archiviano le informazioni sugli utenti in modo esclusivo per ciascuna applicazione, è necessario assicurarsi che lo schema dei dati, le query e gli aggiornamenti includano il nome dell'applicazione. Il comando riportato di seguito, ad esempio, viene utilizzato per recuperare un nome utente da un database in base all'indirizzo di posta elettronica, e garantisce che ApplicationName sia incluso nella query.

SELECT Username FROM MyUserTable 
  WHERE Email = 'someone@example.com' AND ApplicationName = 'MyApplication'

Membri personalizzati

Può essere necessario estendere le interfacce di provider di appartenenze con altre funzionalità non fornite dalle classi astratte ProviderBase e MembershipProvider. Tutti i membri pubblici aggiunti al provider di appartenenze saranno accessibili utilizzando la proprietà Provider o Providers della classe Membership.

Un esempio di questo tipo potrebbe essere un metodo LockUser che imposta la proprietà IsLockedOut su true. Nell'esempio riportato di seguito viene illustrato come eseguire il cast della proprietà Provider, che espone il provider di appartenenze predefinito per un'applicazione, come un tipo di provider personalizzato per chiamare il metodo LockUser personalizzato.

Dim p As MyCustomProvider = CType(Membership.Provider, MyCustomProvider)
p.LockUser(username)
MyCustomProvider p = (MyCustomProvider)Membership.Provider;
p.LockUser(username);

Protezione dei thread

Per ciascun provider di appartenenze specificato nella configurazione di un'applicazione, ASP.NET crea una singola istanza di provider di appartenenze che viene utilizzata per tutte le richieste servite da un oggetto HttpApplication. È possibile quindi che più richieste vengano eseguite simultaneamente. ASP.NET non garantisce la protezione dei thread durante le chiamate al provider. Per ottenere la protezione dei thread sarà necessario scrivere il codice del provider. Ad esempio, la creazione di un database o l'apertura di un file per la modifica deve essere effettuata all'interno del membro che viene chiamato, quale CreateUser, anziché aprire un file o una connessione database quando viene chiamato il metodo Initialize.

Vedere anche

Concetti

Implementazione di un provider di appartenenze di esempio

Protezione del sistema di spostamento all'interno dei siti ASP.NET

Riferimenti

ValidatePasswordEventArgs

OnValidatingPassword

Altre risorse

Gestione di utenti tramite l'appartenenza

Sicurezza dei siti Web ASP.NET