Condividi tramite


Creazione dello schema di appartenenza in SQL Server (C#)

di Scott Mitchell

Nota

Poiché questo articolo è stato scritto, i provider di appartenenza ASP.NET sono stati sostituiti da ASP.NET Identity. Si raccomanda fortemente di aggiornare le app per usare la piattaforma ASP.NET Identity anziché i provider di Membership presenti al momento della scrittura di questo articolo. ASP.NET Identity offre numerosi vantaggi rispetto al sistema di appartenenza ASP.NET, tra cui :

  • Prestazioni migliori
  • Estendibilità e testbilità migliorate
  • Supporto per OAuth, OpenID Connect e autenticazione a due fattori
  • Supporto per le identità basate su attestazioni
  • Migliore interoperabilità con ASP.Net Core

Scaricare codice o Scaricare PDF

Questa esercitazione inizia esaminando le tecniche per aggiungere lo schema necessario al database per usare SqlMembershipProvider. In seguito, verranno esaminate le tabelle chiave nello schema e verranno illustrate le finalità e l'importanza. Questa esercitazione termina con un esame di come indicare a un'applicazione ASP.NET quale provider il framework Membership dovrebbe utilizzare.

Introduzione

Le due esercitazioni precedenti hanno esaminato l'utilizzo dell'autenticazione basata su moduli per identificare i visitatori del sito Web. Il framework di autenticazione basata su moduli consente agli sviluppatori di registrare un utente in un sito Web e di ricordarli durante le visite di pagina tramite l'uso dei ticket di autenticazione. La classe FormsAuthentication include metodi per generare il ticket e aggiungerlo ai cookie del visitatore. Il FormsAuthenticationModule esamina tutte le richieste in ingresso e, per quelle con un ticket di autenticazione valido, crea e associa un GenericPrincipal e un oggetto FormsIdentity alla richiesta corrente. L'autenticazione basata su form è semplicemente un meccanismo per concedere un ticket di autenticazione a un visitatore durante l'accesso e, in caso di richieste successive, l'analisi del ticket per determinare l'identità dell'utente. Per consentire a un'applicazione Web di supportare gli account utente, è comunque necessario implementare un archivio utenti e aggiungere funzionalità per convalidare le credenziali, registrare nuovi utenti e la miriade di altre attività correlate all'account utente.

Prima di ASP.NET 2.0, gli sviluppatori erano responsabili per implementare tutte queste operazioni correlate all'account utente. Fortunatamente il team ASP.NET ha riconosciuto questo problema e ha introdotto il framework di appartenenza con ASP.NET 2.0. Il framework di appartenenza è un set di classi in .NET Framework che forniscono un'interfaccia a livello di codice per eseguire attività principali correlate all'account utente. Questo framework è basato sul modello di provider , che consente agli sviluppatori di collegare un'implementazione personalizzata in un'API standardizzata.

Come discusso nell'esercitazione Security Basics e ASP.NET Support, il .NET Framework viene fornito con due provider di Membership predefiniti: ActiveDirectoryMembershipProvider e SqlMembershipProvider. Come suggerisce il nome, il SqlMembershipProvider usa un database di Microsoft SQL Server come archivio utente. Per usare questo provider in un'applicazione, è necessario specificare al provider quale database da usare come archivio. Come si può immaginare, il SqlMembershipProvider prevede che il database di archiviazione utente disponga di determinate tabelle, viste e stored procedure di database. È necessario aggiungere questo schema previsto al database selezionato.

Questa esercitazione inizia esaminando le tecniche per aggiungere lo schema necessario al database per usare il SqlMembershipProvider. In seguito, verranno esaminate le tabelle chiave nello schema e verranno illustrate le finalità e l'importanza. Questa esercitazione termina con un'analisi su come configurare un'applicazione ASP.NET per utilizzare il provider corretto del framework Membership.

Iniziamo!

Passaggio 1: Decidere dove inserire l'archivio utenti

I dati di un'applicazione ASP.NET vengono in genere archiviati in una serie di tabelle in un database. Quando si implementa lo schema del database SqlMembershipProvider, è necessario decidere se inserire lo schema di appartenenza nello stesso database dei dati dell'applicazione o in un database alternativo.

È consigliabile individuare lo schema di appartenenza nello stesso database dei dati dell'applicazione per i motivi seguenti:

  • Manutenibilità ' un'applicazione i cui dati sono incapsulati in un database è più facile da comprendere, gestire e distribuire rispetto a un'applicazione con due database separati.
  • Integrità Relazionale individuando le tabelle relative all'Iscrizione nello stesso database delle tabelle dell'applicazione, è possibile stabilire vincoli di chiave esterna tra le chiavi primarie delle tabelle relative all'Iscrizione e le tabelle dell'applicazione correlate.

Il disaccoppiamento dei dati dell'utente e dell'applicazione in database separati ha senso solo se sono presenti più applicazioni che usano database separati, ma è necessario condividere un archivio utenti comune.

Creazione di un database

L'applicazione che è stata creata dopo la seconda esercitazione non ha ancora bisogno di un database. Ora ne abbiamo bisogno per l'archivio utenti. Creiamo uno e poi aggiungiamogli lo schema richiesto dal provider di SqlMembershipProvider (vedere Fase 2).

Nota

In questa serie di esercitazioni verrà usato un database di Microsoft SQL Server 2005 Express Edition per archiviare le tabelle dell'applicazione e lo schema SqlMembershipProvider. Questa decisione è stata presa per due motivi: prima, a causa del suo costo gratuito, l'edizione Express è la versione più facilmente accessibile di SQL Server 2005; in secondo luogo, i database di SQL Server 2005 Express Edition possono essere inseriti direttamente nella cartella App_Data dell'applicazione Web, rendendolo un cinch per creare un pacchetto del database e dell'applicazione Web in un unico file ZIP e ridistribuirlo senza istruzioni di installazione o opzioni di configurazione speciali. Se si preferisce seguire l'uso di una versione non Express Edition di SQL Server, è possibile procedere senza problemi. I passaggi sono praticamente identici. Lo schema SqlMembershipProvider funzionerà con qualsiasi versione di Microsoft SQL Server 2000 e versioni successive.

In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella App_Data e scegliere Aggiungi nuovo elemento. Se non viene visualizzata una cartella App_Data nel progetto, fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni, scegliere Aggiungi cartella ASP.NET e scegliere App_Data. Nella finestra di dialogo Aggiungi nuovo elemento scegliere di aggiungere un nuovo database SQL denominato SecurityTutorials.mdf. In questa esercitazione si aggiungerà lo schema SqlMembershipProvider a questo database; nelle esercitazioni successive verranno create tabelle aggiuntive per acquisire i dati dell'applicazione.

Aggiungere un nuovo database SQL denominato SecurityTutorials.mdf database alla cartella App_Data

Figura 1: aggiungere un nuovo database SQL denominato SecurityTutorials.mdf database alla cartella App_Data (fare clic per visualizzare l'immagine a dimensione intera)

L'aggiunta di un database alla cartella App_Data lo include automaticamente nella visualizzazione Esplora database. Nella versione non Express Edition di Visual Studio, Esplora Database viene chiamato Esplora Server. Vai a Esplora Database ed espandi il database SecurityTutorials appena aggiunto. Se Esplora database non è visualizzato nella schermata, passare al menu Visualizza e scegliere Esplora database oppure premere CTRL+ALT+S. Come illustrato nella figura 2, il database SecurityTutorials è vuoto: non contiene tabelle, viste o stored procedure.

Il database SecurityTutorials è attualmente vuoto

figura 2: il database di SecurityTutorials è attualmente vuoto (fare clic per visualizzare l'immagine a dimensione intera)

Passaggio 2: Aggiunta dello schemaSqlMembershipProvideral database

Il SqlMembershipProvider richiede l'installazione di un set specifico di tabelle, viste e stored procedure nel database dell'archivio utenti. Questi oggetti di database necessari possono essere aggiunti usando lo strumento aspnet_regsql.exe. Questo file si trova nella cartella %WINDIR%\Microsoft.Net\Framework\v2.0.50727\.

Nota

Lo strumento aspnet_regsql.exe offre funzionalità della riga di comando e un'interfaccia utente grafica. L'interfaccia grafica è più intuitiva ed è ciò che verrà esaminato in questa esercitazione. L'interfaccia della riga di comando è utile quando è necessario automatizzare l'aggiunta dello schema SqlMembershipProvider, ad esempio negli script di compilazione o negli scenari di test automatizzati.

Lo strumento aspnet_regsql.exe viene usato per aggiungere o rimuovere servizi di applicazione ASP.NET in un database SQL Server specificato. I servizi dell'applicazione ASP.NET comprendono gli schemi per il SqlMembershipProvider e SqlRoleProvider, oltre agli schemi per i provider basati su SQL utilizzati in altri framework di ASP.NET 2.0. È necessario fornire due informazioni allo strumento aspnet_regsql.exe.

  • Se si vogliono aggiungere o rimuovere servizi dell'applicazione e
  • Database da cui aggiungere o rimuovere lo schema dei servizi dell'applicazione

Quando viene richiesto di usare il database, lo strumento aspnet_regsql.exe chiede di specificare il nome del server in cui risiede il database, le credenziali di sicurezza per la connessione al database e il nome del database. Se si usa l'edizione non Express di SQL Server, è necessario conoscere già queste informazioni, poiché sono le stesse informazioni che è necessario fornire tramite una stringa di connessione quando si lavora con il database tramite una pagina Web ASP.NET. Determinare il server e il nome del database quando si usa un database SQL Server 2005 Express Edition nella cartella App_Data, tuttavia, è un po' più complesso.

Nella sezione seguente viene esaminato un modo semplice per specificare il server e il nome del database per un database SQL Server 2005 Express Edition nella cartella App_Data. Se non si usa SQL Server 2005 Express Edition, è possibile passare direttamente alla sezione Installazione dei servizi applicazioni.

Determinazione del server e del nome del database per un database di SQL Server 2005 Express Edition nella cartellaApp_Data

Per usare lo strumento aspnet_regsql.exe è necessario conoscere i nomi del server e del database. Il nome del server è localhost\InstanceName. È probabile che il InstanceName sia SQLExpress. Tuttavia, se SQL Server 2005 Express Edition è stato installato manualmente, ovvero non è stato installato automaticamente durante l'installazione di Visual Studio, è possibile che sia stato selezionato un nome di istanza diverso.

Il nome del database è un po' più complicato da determinare. I database nella cartella App_Data in genere hanno un nome di database che include un identificatore univoco globale insieme al percorso del file di database. È necessario determinare questo nome di database per aggiungere lo schema dei servizi dell'applicazione tramite aspnet_regsql.exe.

Il modo più semplice per verificare il nome del database consiste nell'esaminarlo tramite SQL Server Management Studio. SQL Server Management Studio offre un'interfaccia grafica per la gestione dei database di SQL Server 2005, ma non viene fornita con Express Edition di SQL Server 2005. La buona notizia è che è possibile scaricare l'edizione express gratuita di SQL Server Management Studio.

Nota

Se nel desktop è installata anche una versione non Express Edition di SQL Server 2005, è probabile che sia installata la versione completa di Management Studio. È possibile usare la versione completa per determinare il nome del database, seguendo la stessa procedura descritta di seguito per Express Edition.

Per iniziare, chiudere Visual Studio per assicurarsi che tutti i blocchi imposti da Visual Studio nel file di database siano chiusi. Avviare quindi SQL Server Management Studio e connettersi al database localhost\InstanceName per SQL Server 2005 Express Edition. Come indicato in precedenza, è probabile che il nome dell'istanza sia SQLExpress. Per l'opzione Autenticazione selezionare Autenticazione di Windows.

Collegarsi all'istanza di SQL Server 2005 Express Edition

Figura 3: Connettersi all'istanza di SQL Server 2005 Express Edition (Fare clic per visualizzare l'immagine a schermo intero)

Dopo la connessione all'istanza di SQL Server 2005 Express Edition, Management Studio visualizza le cartelle per i database, le impostazioni di sicurezza, gli oggetti server e così via. Se si espande la scheda Database si noterà che il database SecurityTutorials.mdf non è registrato nell'istanza del database. È necessario collegare prima il database.

Fare clic con il pulsante destro del mouse sulla cartella Database e scegliere Collega dal menu di scelta rapida. Verrà visualizzata la finestra di dialogo Collega database. Da qui, clicca sul pulsante Aggiungi, sfoglia il database SecurityTutorials.mdf e clicca su OK. Nella figura 4 viene visualizzata la finestra di dialogo Collega database dopo aver selezionato il database SecurityTutorials.mdf. La figura 5 mostra l'Esplora oggetti di Management Studio dopo che il database è stato collegato correttamente.

Collegare il database SecurityTutorials.mdf

figura 4: Allegare il database SecurityTutorials.mdf (Fare clic per visualizzare l'immagine a dimensione intera)

Il database SecurityTutorials.mdf viene visualizzato nella cartella Database

figura 5: il database SecurityTutorials.mdf viene visualizzato nella cartella Database (Fare clic per visualizzare l'immagine a dimensione intera)

Come illustrato nella figura 5, il database SecurityTutorials.mdf ha un nome piuttosto astruso. Cambiamolo in un nome più memorabile (e più facile da digitare). Fare clic con il pulsante destro del mouse sul database, scegliere Rinomina dal menu di scelta rapida e rinominarlo SecurityTutorialsDatabase. Questo non modifica il nome del file, ma solo il nome usato dal database per identificarsi in SQL Server.

Rinominare il database in SecurityTutorialsDatabase

figura 6: rinominare il database in SecurityTutorialsDatabase(Fare clic per visualizzare l'immagine a dimensione intera)

A questo punto si conoscono i nomi del server e del database per il file di database SecurityTutorials.mdf: rispettivamente localhost\InstanceName e SecurityTutorialsDatabase. A questo punto è possibile installare i servizi dell'applicazione tramite lo strumento aspnet_regsql.exe.

Installazione dei servizi di applicazione

Per avviare lo strumento aspnet_regsql.exe, passare al menu Start e scegliere Esegui. Immettere %WINDIR%\Microsoft.Net\Framework\v2.0.50727\aspnet_regsql.exe nella casella di testo e fare clic su OK. In alternativa, è possibile usare Esplora File per navigare nella cartella appropriata e fare doppio clic sul file aspnet_regsql.exe. Entrambi gli approcci conterranno gli stessi risultati.

L'esecuzione dello strumento aspnet_regsql.exe senza argomenti della riga di comando avvia l'interfaccia utente grafica dell'installazione guidata di SQL Server ASP.NET. La procedura guidata semplifica l'aggiunta o la rimozione dei servizi dell'applicazione ASP.NET in un database specificato. La prima schermata della procedura guidata, illustrata nella figura 7, descrive lo scopo dello strumento.

usare l'installazione guidata di SQL Server ASP.NET consente di aggiungere lo schema di appartenenza

figura 7: usare l'installazione guidata di SQL Server ASP.NET consente di aggiungere lo schema di appartenenza (fare clic per visualizzare l'immagine a dimensione intera)

Il secondo passaggio della procedura guidata chiede se si vogliono aggiungere i servizi dell'applicazione o rimuoverli. Poiché si vogliono aggiungere le tabelle, le viste e le stored procedure necessarie per il SqlMembershipProvider, scegliere l'opzione Configura SQL Server per i servizi di applicazione. In un secondo momento, se si desidera rimuovere questo schema dal database, eseguire nuovamente questa procedura guidata, ma scegliere invece l'opzione Rimuovi informazioni sui servizi applicazione da un database esistente.

Scegliere l'opzione Configura SQL Server per i servizi applicativi

Figura 8: scegliere l'opzione Configura SQL Server per i servizi applicativi (fare clic per visualizzare l'immagine a dimensione intera)

Il terzo passaggio richiede le informazioni sul database: il nome del server, le informazioni di autenticazione e il nome del database. Se avete seguito questa esercitazione, aggiunto il database SecurityTutorials.mdf a App_Data, allegato a localhost\InstanceNamee rinominato in SecurityTutorialsDatabase, usate i seguenti valori:

  • Server: localhost\InstanceName
  • Autenticazione di Windows
  • Database: SecurityTutorialsDatabase

Immettere le informazioni sul database

figura 9: immettere le informazioni sul database (fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver immesso le informazioni sul database, fare clic su Avanti. Il passaggio finale riepiloga i passaggi che verranno eseguiti. Fare clic su Avanti per installare i servizi dell'applicazione e quindi su Fine per completare la procedura guidata.

Nota

Se è stato usato Management Studio per collegare il database e rinominare il file di database, assicurarsi di scollegare il database e chiudere Management Studio prima di riaprire Visual Studio. Per scollegare il database SecurityTutorialsDatabase, fare clic con il pulsante destro del mouse sul nome del database e scegliere Scollega dal menu delle Attività.

Al termine della procedura guidata, tornare a Visual Studio e passare a Esplora database. Espandi la cartella Tabelle. Verrà visualizzata una serie di tabelle i cui nomi iniziano con il prefisso aspnet_. Analogamente, è possibile trovare un'ampia gamma di viste e stored procedure nelle cartelle Viste e Stored Procedure. Questi oggetti di database costituiscono lo schema dei servizi dell'applicazione. Verranno esaminati gli oggetti di database specifici di appartenenza e ruolo nel passaggio 3.

sono state aggiunte diverse tabelle, viste e procedure memorizzate al database

Figura 10: sono state aggiunte diverse tabelle, viste e stored procedure al database (fare clic per visualizzare l'immagine a dimensione piena)

Nota

L'interfaccia utente grafica dello strumento aspnet_regsql.exe installa l'intero schema dei servizi dell'applicazione. Tuttavia, quando si esegue aspnet_regsql.exe dalla riga di comando, è possibile specificare i componenti specifici dei servizi dell'applicazione da installare o rimuovere. Pertanto, se desidera aggiungere solo le tabelle, le viste e le stored procedure necessarie per i provider SqlMembershipProvider e SqlRoleProvider, eseguire aspnet_regsql.exe dal prompt dei comandi. In alternativa, è possibile eseguire manualmente il subset appropriato di script di creazione T-SQL usati da aspnet_regsql.exe. Questi script si trovano nella cartella WINDIR%\Microsoft.Net\Framework\v2.0.50727\ con nomi come InstallCommon.sql,InstallMembership.sql,InstallRoles.sql, InstallProfile.sql,InstallSqlState.sqle così via.

A questo punto sono stati creati gli oggetti di database necessari per l'SqlMembershipProvider. Tuttavia, è comunque necessario indicare al framework di appartenenza che deve usare il SqlMembershipProvider (anziché, ad esempio, il ActiveDirectoryMembershipProvider) e che il SqlMembershipProvider deve usare il database SecurityTutorials. Verrà illustrato come specificare il provider da usare e come personalizzare le impostazioni del provider selezionato nel passaggio 4. Prima di tutto, si esaminerà in modo più approfondito gli oggetti di database appena creati.

Passaggio 3: Esaminare le tabelle principali dello schema

Quando si utilizzano i framework di appartenenza e ruoli in un'applicazione ASP.NET, i dettagli di implementazione vengono incapsulati dal provider. Nelle esercitazioni future si interfacceranno con questi framework tramite le classi di Membership e Roles di .NET Framework. Quando si usano queste API di alto livello, non è necessario preoccuparsi dei dettagli di basso livello, ad esempio le query eseguite o le tabelle modificate dal SqlMembershipProvider e SqlRoleProvider.

Dato questo, è possibile usare con sicurezza i framework di appartenenza e ruoli senza aver esplorato lo schema del database creato nel passaggio 2. Tuttavia, quando si creano le tabelle per archiviare i dati dell'applicazione, potrebbe essere necessario creare entità correlate a utenti o ruoli. Consente di acquisire familiarità con gli schemi SqlMembershipProvider e SqlRoleProvider quando si stabiliscono vincoli di chiave esterna tra le tabelle dati dell'applicazione e quelle tabelle create nel passaggio 2. Inoltre, in alcune rare circostanze potrebbe essere necessario interfacciarsi con gli archivi utente e ruolo direttamente a livello di database (anziché tramite le classi Membership o Roles).

Partizionamento dell'archivio utenti in applicazioni

I framework di appartenenza e ruoli sono progettati in modo che un singolo utente e un archivio ruoli possano essere condivisi tra molte applicazioni diverse. Un'applicazione ASP.NET che usa i framework di appartenenza o ruoli deve specificare la partizione dell'applicazione da usare. In breve, più applicazioni Web possono usare gli stessi archivi utenti e ruoli. La figura 11 illustra gli archivi utenti e ruoli partizionati in tre applicazioni: HRSite, CustomerSite e SalesSite. Queste tre applicazioni Web dispongono di ruoli e utenti univoci, ma archiviano fisicamente l'account utente e le informazioni sul ruolo nelle stesse tabelle di database.

gli account utente possono essere partizionati tra più applicazioni

Figura 11: Gli account utente potrebbero essere partizionati in più applicazioni (Clicca per visualizzare l'immagine a dimensione intera)

La tabella aspnet_Applications definisce queste partizioni. Ogni applicazione che usa il database per archiviare le informazioni sull'account utente è rappresentata da una riga in questa tabella. La tabella aspnet_Applications include quattro colonne: ApplicationId, ApplicationName, LoweredApplicationNamee Description. ApplicationId è di tipo uniqueidentifier ed è la chiave primaria della tabella; ApplicationName fornisce un nome univoco e comprensibile per ogni applicazione.

Le altre tabelle correlate all'appartenenza e al ruolo si collegano di nuovo al campo ApplicationId in aspnet_Applications. Ad esempio, la tabella aspnet_Users, che contiene un record per ogni account utente, ha un campo ApplicationId chiave esterna; lo stesso vale per la tabella aspnet_Roles. Il campo ApplicationId in queste tabelle specifica la partizione dell'applicazione a cui appartiene l'account utente o il ruolo.

Archiviazione delle informazioni sull'account utente

Le informazioni sull'account utente sono ospitate in due tabelle: aspnet_Users e aspnet_Membership. La tabella aspnet_Users contiene campi che contengono le informazioni essenziali sull'account utente. Le tre colonne più pertinenti sono:

  • UserId
  • UserName
  • ApplicationId

UserId è la chiave primaria (ed è di tipo uniqueidentifier). UserName è di tipo nvarchar(256) e, insieme alla password, costituisce le credenziali dell'utente. La password di un utente viene archiviata nella tabella aspnet_Membership. ApplicationId collega l'account utente a una determinata applicazione in aspnet_Applications. Esiste un vincolo UNIQUE composito nelle colonne UserName e ApplicationId. In questo modo si garantisce che in una determinata applicazione ogni UserName sia univoco, ma consenta l'uso dello stesso UserName in applicazioni diverse.

La tabella aspnet_Membership include informazioni aggiuntive sull'account utente, ad esempio la password dell'utente, l'indirizzo di posta elettronica, la data e l'ora dell'ultimo accesso e così via. Esiste una corrispondenza uno-a-uno tra i record nelle tabelle aspnet_Users e aspnet_Membership. Questa relazione viene garantita dal campo UserId in aspnet_Membership, che funge da chiave primaria della tabella. Analogamente alla tabella aspnet_Users, aspnet_Membership include un campo ApplicationId che collega queste informazioni a una determinata partizione dell'applicazione.

Protezione delle password

Le informazioni sulla password vengono archiviate nella tabella aspnet_Membership. Il SqlMembershipProvider consente di archiviare le password nel database usando una delle tre tecniche seguenti:

  • Cancella: la password viene archiviata nel database come testo normale. Sconsiglio vivamente di usare questa opzione. Se il database viene compromesso, ad esempio da un hacker che trova una porta posteriore o un dipendente scontento che ha accesso al database, le credenziali di ogni singolo utente sono lì per l'acquisizione.
  • Hashed: le password vengono con hashing usando un algoritmo hash unidirezionale e un valore salt generato in modo casuale. Questo valore con hash (insieme al salt) viene archiviato nel database.
  • crittografato: nel database viene archiviata una versione crittografata della password.

La tecnica di archiviazione delle password usata dipende dalle impostazioni di SqlMembershipProvider specificate in Web.config. Si esaminerà la personalizzazione delle impostazioni di SqlMembershipProvider nel passaggio 4. Il comportamento predefinito consiste nell'archiviare l'hash della password.

Le colonne responsabili dell'archiviazione della password sono Password, PasswordFormate PasswordSalt. PasswordFormat è un campo di tipo int il cui valore indica la tecnica usata per archiviare la password: 0 per Clear; 1 per Hashed; 2 per Encrypted. PasswordSalt viene assegnata una stringa generata in modo casuale indipendentemente dalla tecnica di archiviazione delle password usata; Il valore di PasswordSalt viene usato solo quando si calcola l'hash della password. Infine, la colonna Password contiene i dati effettivi della password, ad esempio la password in testo normale, l'hash della password o la password crittografata.

La tabella 1 illustra l'aspetto di queste tre colonne per le varie tecniche di archiviazione quando si archivia la password MySecret! .

Tecnica di archiviazione<_o3a_p/> password<_o3a_p/> PasswordFormat<_o3a_p/> PasswordSalt<_o3a_p/>
Chiaro MySecret! 0 tTnkPlesqissc2y2SMEygA==
Sottoposto a hash 2oXm6sZHWbTHFgjgkGQsc2Ec9ZM= 1 wFgjUfhdUFOCKQiI61vtiQ==
Criptato 62RZgDvhxykkqsMchZ0Yly7HS6onhpaoCYaRxV8g0F4CW56OXUU3e7Inza9j9BKp 2 LSRzhGS/aa/oqAXGLHJNBw==

Tabella 1: valori di esempio per i campi Password-Related durante l'archiviazione della password MySecret!

Nota

L'algoritmo di crittografia o hash specifico utilizzato dal SqlMembershipProvider è determinato dalle impostazioni nell'elemento <machineKey>.

Archiviazione di ruoli e associazioni di ruoli

Il framework Ruoli consente agli sviluppatori di definire un set di ruoli e specificare a quali ruoli appartengono gli utenti. Queste informazioni vengono acquisite nel database tramite due tabelle: aspnet_Roles e aspnet_UsersInRoles. Ogni record nella tabella aspnet_Roles rappresenta un ruolo per una determinata applicazione. Analogamente alla tabella aspnet_Users, la tabella aspnet_Roles include tre colonne pertinenti alla discussione:

  • RoleId
  • RoleName
  • ApplicationId

RoleId è la chiave primaria (e di tipo uniqueidentifier). RoleName è di tipo nvarchar(256). E ApplicationId collega l'account utente a una determinata applicazione in aspnet_Applications. Esiste un vincolo composito UNIQUE sulle colonne RoleName e ApplicationId, che garantisce l'unicità del nome di ogni ruolo all'interno di una data applicazione.

La tabella aspnet_UsersInRoles funge da mappatura tra utenti e ruoli. Esistono solo due colonne, UserId e RoleId, e insieme costituiscono una chiave primaria composita.

Passaggio 4: Specifica del fornitore e personalizzazione delle relative impostazioni

Tutti i framework che supportano il modello di provider, ad esempio i framework appartenenza e ruoli, non dispongono di dettagli di implementazione e delegano invece tale responsabilità a una classe del provider. Nel caso del framework Membership, la classe Membership definisce l'API per la gestione degli account utente, ma non interagisce direttamente con alcun archivio utenti. Invece, i metodi della classe Membership consegnano la richiesta al provider configurato. Verrà usato il SqlMembershipProvider. Quando si richiama uno dei metodi nella classe Membership, come fa il framework Membership a sapere di dover delegare la chiamata al SqlMembershipProvider?

La classe Membership dispone di una proprietà Providers che contiene un riferimento a tutte le classi di provider registrate disponibili per l'uso da parte del framework Membership. Ogni provider registrato ha un nome e un tipo associati. Il nome offre un modo intuitivo per fare riferimento a un determinato provider nella raccolta Providers, mentre il tipo indica la classe del provider. Inoltre, ogni provider registrato può includere le impostazioni di configurazione. Le impostazioni di configurazione per il framework di appartenenza includono passwordFormat e requiresUniqueEmail, tra le altre. Per un elenco completo delle impostazioni di configurazione usate dal SqlMembershipProvider, vedere la tabella 2.

Il contenuto della proprietà Providers viene specificato tramite le impostazioni di configurazione dell'applicazione Web. Per impostazione predefinita, tutte le applicazioni Web hanno un provider denominato AspNetSqlMembershipProvider di tipo SqlMembershipProvider. Questo provider di membership predefinito è registrato in machine.config (disponibile in %WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG):

Avvertimento

Sembra che l'esempio che stai cercando sia stato spostato! Siamo certi che stiamo lavorando per risolvere questo problema.

Come illustrato nel markup precedente, l'elemento <membership>, definisce le impostazioni di configurazione per il framework Membership, mentre l'elemento figlio <providers>, specifica i provider registrati. I provider possono essere aggiunti o rimossi utilizzando gli elementi <add> o <remove>; utilizzare l'elemento <clear> per rimuovere tutti i provider attualmente registrati. Come illustrato nel markup precedente, machine.config aggiunge un provider denominato AspNetSqlMembershipProvider di tipo SqlMembershipProvider.

Oltre agli attributi name e type, l'elemento <add> contiene attributi che definiscono i valori per varie impostazioni di configurazione. Nella tabella 2 sono elencate le impostazioni di configurazione specifiche per SqlMembershipProviderdisponibili, insieme a una descrizione di ciascuna.

Nota

Tutti i valori predefiniti indicati nella tabella 2 fanno riferimento ai valori predefiniti definiti nella classe SqlMembershipProvider. Si noti che non tutte le impostazioni di configurazione in AspNetSqlMembershipProvider corrispondono ai valori predefiniti della classe SqlMembershipProvider. Ad esempio, se non specificato in un provider di appartenenze, l'impostazione predefinita di requiresUniqueEmail è true. Tuttavia, il AspNetSqlMembershipProvider esegue l'override di questo valore predefinito specificando in modo esplicito un valore di false.

impostazione <_o3a_p/> Descrizione<_o3a_p/>
ApplicationName Tenere presente che il framework di appartenenza consente di partizionare un singolo archivio utenti tra più applicazioni. Questa impostazione indica il nome della partizione dell'applicazione usata dal provider di membership. Se questo valore non viene specificato in modo esplicito, viene impostato, in fase di esecuzione, sul valore del percorso radice virtuale dell'applicazione.
commandTimeout Specifica il valore di timeout del comando SQL (in secondi). Il valore predefinito è 30.
connectionStringName Nome della stringa di connessione nell'elemento <connectionStrings> da utilizzare per connettersi al database dell'archivio utenti. Questo valore è obbligatorio.
description Fornisce una descrizione comprensibile del provider registrato.
enablePasswordRetrieval Specifica se gli utenti possono recuperare la password dimenticata. Il valore predefinito è false.
enablePasswordReset Indica se gli utenti possono reimpostare la password. Il valore predefinito è true.
maxInvalidPasswordAttempts Numero massimo di tentativi di accesso non riusciti che possono verificarsi per un determinato utente durante il passwordAttemptWindow specificato prima che l'utente venga bloccato. Il valore predefinito è 5.
minRequiredNonalphanumericCharacters Numero minimo di caratteri non alfanumerici che devono essere visualizzati nella password di un utente. Questo valore deve essere compreso tra 0 e 128; il valore predefinito è 1.
minRequiredPasswordLength Numero minimo di caratteri necessari in una password. Questo valore deve essere compreso tra 0 e 128; il valore predefinito è 7.
name Nome del provider registrato. Questo valore è obbligatorio.
passwordAttemptWindow Numero di minuti durante i quali vengono rilevati tentativi di accesso non riusciti. Se un utente fornisce credenziali di accesso non valide maxInvalidPasswordAttempts volte all'interno di questa finestra specificata, vengono bloccate. Il valore predefinito è 10.
PasswordFormat Formato di archiviazione delle password: Clear, Hashedo Encrypted. Il valore predefinito è Hashed.
passwordStrengthRegularExpression Se specificato, questa espressione regolare viene usata per valutare il livello di attendibilità della password selezionata dall'utente durante la creazione di un nuovo account o quando si modifica la password. Il valore predefinito è una stringa vuota.
requiresQuestionAndAnswer Specifica se un utente deve rispondere alla domanda di sicurezza durante il recupero o la reimpostazione della password. Il valore predefinito è true.
requiresUniqueEmail Indica se tutti gli account utente in una determinata partizione dell'applicazione devono avere un indirizzo di posta elettronica univoco. Il valore predefinito è true.
type Specifica il tipo del provider. Questo valore è obbligatorio.

Tabella 2: Appartenenza e impostazioni di configurazione SqlMembershipProvider

Oltre a AspNetSqlMembershipProvider, altri provider di membership possono essere registrati per ogni applicazione aggiungendo un markup simile nel file Web.config.

Nota

Il framework dei ruoli funziona in modo molto simile: esiste un provider di ruoli predefinito registrato in machine.config e i provider registrati possono essere personalizzati per ciascuna applicazione in Web.config. Esamineremo in dettaglio il framework Ruoli e il suo markup di configurazione in un futuro tutorial.

Personalizzazione delle impostazioni diSqlMembershipProvider

Il SqlMembershipProvider predefinito (AspNetSqlMembershipProvider) ha l'attributo connectionStringName impostato su LocalSqlServer. Analogamente al provider di AspNetSqlMembershipProvider, il nome della stringa di connessione LocalSqlServer viene definito in machine.config.

Avvertimento

Sembra che l'esempio che stai cercando sia stato spostato! Siamo certi che stiamo lavorando per risolvere questo problema.

Come si può notare, questa stringa di connessione definisce un database SQL 2005 Express Edition disponibile in |DataDirectory|aspnetdb.mdf'. Stringa |DataDirectory | viene convertito in fase di esecuzione in modo che punti alla directory ~/App_Data/, quindi il percorso del database |DataDirectory|aspnetdb.mdf" viene convertito in ~/App_Data/aspnet.mdf.

Se non specifichiamo alcuna informazione sul provider di membership nel file Web.config della nostra applicazione, l'applicazione utilizza il provider di membership registrato predefinito, AspNetSqlMembershipProvider. Se il database ~/App_Data/aspnet.mdf non esiste, il runtime di ASP.NET lo creerà automaticamente e aggiungerà lo schema dei servizi dell'applicazione. Tuttavia, non si vuole usare il database aspnet.mdf; si vuole invece usare il database SecurityTutorials.mdf creato nel passaggio 2. Questa modifica può essere eseguita in uno dei due modi seguenti:

  • Specificare un valore per il nome della stringa di connessioneLocalSqlServerinWeb.config. Sovrascrivendo il valore del nome della stringa di connessione LocalSqlServer in Web.config, è possibile usare il provider di Membership registrato predefinito (AspNetSqlMembershipProvider) e garantire il suo corretto funzionamento con il database SecurityTutorials.mdf. Questo approccio è corretto se si è soddisfatti delle impostazioni di configurazione specificate da AspNetSqlMembershipProvider. Per altre informazioni su questa tecnica, vedere post di blog di Scott GuthrieConfiguring ASP.NET 2.0 Application Services to Use SQL Server 2000 or SQL Server 2005.
  • Aggiungere un nuovo provider registrato di tipoSqlMembershipProvidere configurarne l'impostazioneconnectionStringNamein modo che punti al databaseSecurityTutorials.mdf. Questo approccio è utile negli scenari in cui si desidera personalizzare altre proprietà di configurazione oltre alla stringa di connessione del database. Nei miei progetti uso sempre questo approccio grazie alla sua flessibilità e leggibilità.

Prima di poter aggiungere un nuovo provider registrato che fa riferimento al database SecurityTutorials.mdf, è prima necessario aggiungere un valore della stringa di connessione appropriato nella sezione <connectionStrings> in Web.config. Il markup seguente aggiunge una nuova stringa di connessione denominata SecurityTutorialsConnectionString che fa riferimento al database SecurityTutorials.mdf di SQL Server 2005 Express Edition nella cartella App_Data.

Avvertimento

Sembra che l'esempio che stai cercando sia stato spostato! Siamo certi che stiamo lavorando per risolvere questo problema.

Nota

Se si usa un file di database alternativo, aggiornare la stringa di connessione in base alle esigenze. Per altre informazioni sulla creazione della stringa di connessione corretta, vedere ConnectionStrings.com.

Aggiungere quindi il markup di configurazione di appartenenza seguente al file Web.config. Questo markup registra un nuovo provider denominato SecurityTutorialsSqlMembershipProvider.

Avvertimento

Sembra che l'esempio che stai cercando sia stato spostato! Siamo certi che stiamo lavorando per risolvere questo problema.

Oltre a registrare il provider di SecurityTutorialsSqlMembershipProvider, il markup precedente definisce il SecurityTutorialsSqlMembershipProvider come provider predefinito (tramite l'attributo defaultProvider nell'elemento <membership>). Tenere presente che il framework Membership può avere più provider registrati. Poiché AspNetSqlMembershipProvider è registrato come primo provider in machine.config, funge da provider predefinito, a meno che non venga indicato diversamente.

Attualmente, l'applicazione ha due provider registrati: AspNetSqlMembershipProvider e SecurityTutorialsSqlMembershipProvider. Tuttavia, prima di registrare il provider di SecurityTutorialsSqlMembershipProvider, potremmo eliminare tutti i provider registrati in precedenza aggiungendo un elemento <clear /> immediatamente prima dell'elemento <add>. Ciò consente di cancellare il AspNetSqlMembershipProvider dall'elenco dei provider registrati, vale a dire che il SecurityTutorialsSqlMembershipProvider sarebbe l'unico provider di appartenenze registrato. Se si usasse questo approccio, non sarebbe necessario contrassegnare il SecurityTutorialsSqlMembershipProvider come provider predefinito, perché sarebbe l'unico provider di appartenenze registrato. Per altre informazioni sull'uso di <clear />, vedere Utilizzo di <clear /> durante l'aggiunta di fornitori.

Si noti che l'impostazione connectionStringName dell'SecurityTutorialsSqlMembershipProviderfa riferimento al nome della stringa di connessione appena aggiunta SecurityTutorialsConnectionString e che l'impostazione applicationName è stata impostata su un valore di SecurityTutorials. Inoltre, l'impostazione requiresUniqueEmail è stata impostata su true. Tutte le altre opzioni di configurazione sono identiche ai valori in AspNetSqlMembershipProvider. Se lo si desidera, è possibile apportare eventuali modifiche alla configurazione. Ad esempio, è possibile restringere la complessità della password richiedendo due caratteri non alfanumerici anziché uno o aumentando la lunghezza della password a otto caratteri anziché sette.

Nota

Tenere presente che il framework di appartenenza consente di partizionare un singolo archivio utenti tra più applicazioni. L'impostazione applicationName del provider di gestione utenti indica quale applicazione il provider utilizza quando lavora con l'archivio utenti. È importante impostare in modo esplicito un valore per l'impostazione di configurazione applicationName perché se il applicationName non è impostato in modo esplicito, viene assegnato al percorso radice virtuale dell'applicazione Web in fase di esecuzione. Questa operazione funziona correttamente finché il percorso radice virtuale dell'applicazione non cambia, ma se si sposta l'applicazione in un percorso diverso, anche l'impostazione applicationName cambierà. In questo caso, il provider di appartenenze inizierà a lavorare con una partizione dell'applicazione diversa rispetto a quella usata in precedenza. Gli account utente creati prima dello spostamento si troveranno in una partizione diversa dell'applicazione e tali utenti non potranno più accedere al sito. Per una discussione più approfondita su questo argomento, vedere Impostare sempre la proprietà applicationName durante la configurazione dell'appartenenza ASP.NET 2.0 e di altri provider.

Sommario

A questo punto, abbiamo un database con i servizi dell'applicazione configurati (SecurityTutorials.mdf) e abbiamo configurato la nostra applicazione web affinché il framework Membership utilizzi il provider SecurityTutorialsSqlMembershipProvider appena registrato. Questo provider registrato è di tipo SqlMembershipProvider e ha il relativo connectionStringName impostato sulla stringa di connessione appropriata (SecurityTutorialsConnectionString) e il relativo valore applicationName impostato in modo esplicito.

A questo punto siamo pronti per utilizzare il framework Membership dalla nostra applicazione. Nell'esercitazione successiva verrà illustrato come creare nuovi account utente. Successivamente esploreremo come autenticare gli utenti, eseguire l'autorizzazione basata sugli utenti e archiviare ulteriori informazioni relative agli utenti nel database.

Buon programmatori!

Altre informazioni

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

Formazione video sugli argomenti contenuti in questa esercitazione

Informazioni sull'autore

Scott Mitchell, autore di più libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è "Sams Teach Yourself ASP.NET 2.0 in 24 Hours". Scott può essere raggiunto a 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 collaborativi. Il revisore principale per questa guida è stata Alicja Maziarz. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, mandami un messaggio a mitchell@4GuysFromRolla.com.