Panoramica dell'autenticazione basata su form (C#)

di Scott Mitchell

Nota

Poiché questo articolo è stato scritto, i provider di appartenenze ASP.NET sono stati sostituiti da ASP.NET Identity. È consigliabile aggiornare le app per usare ASP.NET Identity Platform anziché i provider di appartenenze in primo piano al momento della scrittura di questo articolo. ASP.NET Identity presenta diversi 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
  • Migliore interoperabilità con ASP.Net Core

Scaricare il codice o scaricare il PDF

In questa esercitazione si passerà dalla semplice discussione all'implementazione; in particolare, si esaminerà l'implementazione dell'autenticazione basata su form. L'applicazione Web che verrà avviata in questa esercitazione continuerà a essere compilata nelle esercitazioni successive, passando dall'autenticazione basata su moduli semplici all'appartenenza e ai ruoli.

Per altre informazioni su questo argomento, vedere questo video: Uso dell'autenticazione basata su form di base in ASP.NET.

Introduzione

Nell'esercitazione precedente sono illustrate le varie opzioni di autenticazione, autorizzazione e account utente fornite da ASP.NET. In questa esercitazione si passerà dalla semplice discussione all'implementazione; in particolare, si esaminerà l'implementazione dell'autenticazione basata su form. L'applicazione Web che verrà avviata in questa esercitazione continuerà a essere compilata nelle esercitazioni successive, passando dall'autenticazione basata su moduli semplici all'appartenenza e ai ruoli.

Questa esercitazione inizia con un'analisi approfondita del flusso di lavoro di autenticazione dei moduli, un argomento illustrato nell'esercitazione precedente. Successivamente, verrà creato un sito Web di ASP.NET tramite il quale demo i concetti di autenticazione basata su moduli. Successivamente, si configurerà il sito per l'uso dell'autenticazione basata su form, si creerà una semplice pagina di accesso e si vedrà come determinare, nel codice, se un utente è autenticato e, in tal caso, il nome utente con cui ha eseguito l'accesso.

Comprendere il flusso di lavoro di autenticazione basata su form, abilitarlo in un'applicazione Web e creare le pagine di accesso e disconnessione sono tutti passaggi fondamentali per la creazione di un'applicazione ASP.NET che supporta gli account utente e autentica gli utenti tramite una pagina Web. Per questo motivo, e poiché queste esercitazioni si basano l'una sull'altra, è consigliabile eseguire questa esercitazione in modo completo prima di passare a quella successiva anche se si è già avuto esperienza nella configurazione dell'autenticazione basata su moduli nei progetti precedenti.

Informazioni sul flusso di lavoro di autenticazione basata su form

Quando il runtime di ASP.NET elabora una richiesta per una risorsa ASP.NET, ad esempio una pagina ASP.NET o ASP.NET servizio Web, la richiesta genera un numero di eventi durante il ciclo di vita. Ci sono eventi generati all'inizio e alla fine della richiesta, quelli generati quando la richiesta viene autenticata e autorizzata, un evento generato nel caso di un'eccezione non gestita e così via. Per visualizzare un elenco completo degli eventi, vedere gli eventi dell'oggetto HttpApplication.

I moduli HTTP sono classi gestite il cui codice viene eseguito in risposta a un determinato evento nel ciclo di vita della richiesta. ASP.NET viene fornito con diversi moduli HTTP che eseguono attività essenziali dietro le quinte. Due moduli HTTP predefiniti particolarmente rilevanti per la discussione sono:

  • FormsAuthenticationModule : autentica l'utente controllando il ticket di autenticazione dei moduli, che in genere è incluso nella raccolta di cookie dell'utente. Se non è presente alcun ticket di autenticazione basata su form, l'utente è anonimo.
  • UrlAuthorizationModule : determina se l'utente corrente è autorizzato ad accedere all'URL richiesto. Questo modulo determina l'autorità consultando le regole di autorizzazione specificate nei file di configurazione dell'applicazione. ASP.NET include anche l'oggetto che determina l'autorità FileAuthorizationModule consultando gli ACL dei file richiesti.

Tenta FormsAuthenticationModule di autenticare l'utente prima dell'esecuzione di UrlAuthorizationModule (e FileAuthorizationModule). Se l'utente che effettua la richiesta non è autorizzato ad accedere alla risorsa richiesta, il modulo di autorizzazione termina la richiesta e restituisce uno stato HTTP 401 Non autorizzato . Negli scenari autenticazione di Windows, lo stato HTTP 401 viene restituito al browser. Questo codice di stato consente al browser di richiedere all'utente le credenziali tramite una finestra di dialogo modale. Con l'autenticazione basata su form, tuttavia, lo stato HTTP 401 Non autorizzato non viene mai inviato al browser perché FormsAuthenticationModule rileva questo stato e lo modifica per reindirizzare l'utente alla pagina di accesso (tramite uno stato di reindirizzamento HTTP 302 ).

La responsabilità della pagina di accesso consiste nel determinare se le credenziali dell'utente sono valide e, in tal caso, per creare un ticket di autenticazione basata su moduli e reindirizzare l'utente alla pagina che stava tentando di visitare. Il ticket di autenticazione è incluso nelle richieste successive alle pagine del sito Web, che FormsAuthenticationModule usa per identificare l'utente.

Flusso di lavoro di autenticazione basata su form

Figura 1: Flusso di lavoro di autenticazione basata su form

Memorizzazione del ticket di autenticazione tra le visite di pagina

Dopo l'accesso, il ticket di autenticazione dei moduli deve essere inviato al server Web in ogni richiesta in modo che l'utente rimanga connesso mentre esplora il sito. Questa operazione viene in genere eseguita inserendo il ticket di autenticazione nella raccolta di cookie dell'utente. I cookie sono file di testo di piccole dimensioni che risiedono nel computer dell'utente e vengono trasmessi nelle intestazioni HTTP su ogni richiesta al sito Web che ha creato il cookie. Pertanto, dopo aver creato e archiviato il ticket di autenticazione dei moduli nei cookie del browser, ogni visita successiva a tale sito invia il ticket di autenticazione insieme alla richiesta, identificando l'utente.

Un aspetto dei cookie è la scadenza, ovvero la data e l'ora in cui il browser elimina il cookie. Alla scadenza del cookie di autenticazione basata su form, l'utente non può più essere autenticato e pertanto diventa anonimo. Quando un utente visita da un terminale pubblico, è probabile che il ticket di autenticazione scada quando chiude il browser. Quando si visita da casa, tuttavia, lo stesso utente potrebbe voler ricordare il ticket di autenticazione tra i riavvii del browser in modo che non sia necessario ripetere l'accesso ogni volta che visitano il sito. Questa decisione viene spesso presa dall'utente sotto forma di casella di controllo "Ricordami" nella pagina di accesso. Nel passaggio 3 verrà illustrato come implementare una casella di controllo "Ricordami" nella pagina di accesso. L'esercitazione seguente illustra in dettaglio le impostazioni di timeout del ticket di autenticazione.

Nota

È possibile che l'agente utente usato per accedere al sito Web non supporti i cookie. In questo caso, ASP.NET possono usare ticket di autenticazione basata su form senza cookie. In questa modalità, il ticket di autenticazione viene codificato nell'URL. Si esaminerà quando vengono usati i ticket di autenticazione senza cookie e come vengono creati e gestiti nell'esercitazione successiva.

Ambito dell'autenticazione basata su form

FormsAuthenticationModule è codice gestito che fa parte del runtime ASP.NET. Prima della versione 7 del server Web Internet Information Services (IIS) di Microsoft, esiste una barriera distinta tra la pipeline HTTP di IIS e la pipeline del runtime di ASP.NET. In breve, in IIS 6 e versioni precedenti, viene FormsAuthenticationModule eseguito solo quando una richiesta viene delegata da IIS al runtime di ASP.NET. Per impostazione predefinita, IIS elabora il contenuto statico stesso, ad esempio pagine HTML e file CSS e image, e passa le richieste solo al runtime di ASP.NET quando viene richiesta una pagina con estensione di .aspx, asmx o ashx.

IIS 7 consente tuttavia l'integrazione di IIS e ASP.NET pipeline. Con alcune impostazioni di configurazione è possibile configurare IIS 7 per richiamare FormsAuthenticationModule per tutte le richieste. Inoltre, con IIS 7 è possibile definire regole di autorizzazione URL per i file di qualsiasi tipo. Per altre informazioni, vedere Modifiche tra SICUREZZA IIS6 e IIS7, Sicurezza della piattaforma Web e Informazioni sull'autorizzazione DEGLI URL IIS7.

Breve storia, nelle versioni precedenti a IIS 7, è possibile usare l'autenticazione basata su form solo per proteggere le risorse gestite dal runtime di ASP.NET. Analogamente, le regole di autorizzazione URL vengono applicate solo alle risorse gestite dal runtime di ASP.NET. Tuttavia, con IIS 7 è possibile integrare FormsAuthenticationModule e UrlAuthorizationModule nella pipeline HTTP di IIS, estendendo questa funzionalità a tutte le richieste.

Passaggio 1: Creazione di un sito Web ASP.NET per questa serie di esercitazioni

Per raggiungere il pubblico più ampio possibile, il sito Web ASP.NET che verrà creato in questa serie verrà creato con la versione gratuita di Visual Studio 2008, Visual Web Developer 2008. L'archivio SqlMembershipProvider utenti verrà implementato in un database di Microsoft SQL Server 2005 Express Edition. Se si usa Visual Studio 2005 o un'edizione diversa di Visual Studio 2008 o SQL Server, non preoccuparti. I passaggi saranno quasi identici e verranno evidenziate eventuali differenze non semplici.

Nota

L'applicazione Web demo usata in ogni esercitazione è disponibile come download. Questa applicazione scaricabile è stata creata con Visual Web Developer 2008 destinato a .NET Framework versione 3.5. Poiché l'applicazione è destinata a .NET 3.5, il file di Web.config include elementi di configurazione aggiuntivi specifici di 3.5. Breve storia, se è ancora necessario installare .NET 3.5 nel computer, l'applicazione Web scaricabile non funzionerà senza prima rimuovere il markup specifico 3.5 da Web.config.

Prima di poter configurare l'autenticazione basata su moduli, è necessario un sito Web ASP.NET. Per iniziare, creare un nuovo sito Web basato sul file system ASP.NET. A tale scopo, avviare Visual Web Developer e quindi passare al menu File e scegliere Nuovo sito Web, visualizzando la finestra di dialogo Nuovo sito Web. Scegliere il modello ASP.NET sito Web, impostare l'elenco a discesa Percorso su File System, scegliere una cartella in cui inserire il sito Web e impostare la lingua su C#. Verrà creato un nuovo sito Web con una pagina Default.aspx ASP.NET, una cartella App_Data e un file di Web.config.

Nota

Visual Studio supporta due modalità di gestione dei progetti: progetti di siti Web e progetti di applicazioni Web. I progetti di siti Web non dispongono di un file di progetto, mentre i progetti applicazione Web simulano l'architettura del progetto in Visual Studio .NET 2002/2003, includono un file di progetto e compilano il codice sorgente del progetto in un singolo assembly, che viene inserito nella cartella /bin. Visual Studio 2005 inizialmente supporta solo progetti di siti Web, anche se il modello Progetto applicazione Web è stato reintrodotto con Service Pack 1; Visual Studio 2008 offre entrambi i modelli di progetto. Le edizioni Visual Web Developer 2005 e 2008, tuttavia, supportano solo progetti di siti Web. Verrà usato il modello Progetto sito Web. Se si usa un'edizione non Express e si vuole usare invece il modello Progetto applicazione Web , è possibile farlo, ma tenere presente che potrebbero esserci alcune discrepanze tra ciò che viene visualizzato sullo schermo e i passaggi da eseguire rispetto alle schermate visualizzate e alle istruzioni fornite in queste esercitazioni.

Creare un nuovo file System-Based sito Web

Figura 2: Creare un nuovo file System-Based sito Web (fare clic per visualizzare l'immagine a dimensione intera)

Aggiunta di una pagina master

Aggiungere quindi una nuova pagina master al sito nella directory radice denominata Site.master. Le pagine master consentono a uno sviluppatore di pagine di definire un modello a livello di sito che può essere applicato alle pagine ASP.NET. Il vantaggio principale delle pagine master è che l'aspetto complessivo del sito può essere definito in una singola posizione, rendendo così facile aggiornare o modificare il layout del sito.

Aggiungere una pagina master denominata Site.master al sito Web

Figura 3: Aggiungere una pagina master denominata Site.master al sito Web (fare clic per visualizzare l'immagine full-size)

Definire il layout della pagina a livello di sito qui nella pagina master. È possibile usare la visualizzazione Progettazione e aggiungere qualsiasi controllo Layout o Web necessario oppure è possibile aggiungere manualmente il markup in base alla visualizzazione Origine. Ho strutturato il layout della pagina master per simulare il layout usato nella mia serie di esercitazioni Working with Data in ASP.NET serie di esercitazioni 2.0 (vedere la figura 4). La pagina master usa fogli di stile a catena per posizionare e stili con le impostazioni CSS definite nel file Style.css (incluso nel download associato di questa esercitazione). Anche se non è possibile indicare dal markup illustrato di seguito, le regole CSS sono definite in modo che il contenuto del div> di navigazione <sia assolutamente posizionato in modo che venga visualizzato a sinistra e abbia una larghezza fissa di 200 pixel.

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Site.master.cs" Inherits="Site" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Forms Authentication, Authorization, and User Accounts</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <div id="wrapper">
        <form id="form1" runat="server">
        
            <div id="header">
                <span class="title">User Account Tutorials</span>
            </div>
        
            <div id="content">
                <asp:contentplaceholder id="MainContent" runat="server">
                  <!-- Page-specific content will go here... -->
                </asp:contentplaceholder>
            </div>
            
            <div id="navigation">
                TODO: Menu will go here...
            </div>
        </form>
    </div>
</body>
</html>

Una pagina master definisce sia il layout di pagina statico che le aree che possono essere modificate dalle pagine ASP.NET che usano la pagina master. Queste aree modificabili contenuto sono indicate dal controllo, che può essere visualizzato all'interno del ContentPlaceHolder contenuto <div>. La pagina master include una singola ContentPlaceHolder pagina (MainContent), ma la pagina master può avere più ContentPlaceHolder.

Con il markup immesso sopra, passare alla visualizzazione Progettazione mostra il layout della pagina master. Tutte le pagine ASP.NET che usano questa pagina master avranno questo layout uniforme, con la possibilità di specificare il markup per l'area MainContent .

Pagina master, quando visualizzata tramite la visualizzazione progettazione

Figura 4: Pagina master, quando visualizzata tramite la visualizzazione progettazione (fare clic per visualizzare l'immagine a dimensioni complete)

Creazione di pagine contenuto

A questo punto abbiamo una pagina Default.aspx nel nostro sito Web, ma non usa la pagina master appena creata. Anche se è possibile modificare il markup dichiarativo di una pagina Web per usare una pagina master, se la pagina non contiene ancora contenuto è più semplice eliminare la pagina e aggiungerla nuovamente al progetto, specificando la pagina master da usare. Pertanto, iniziare eliminando Default.aspx dal progetto.

Fare quindi clic con il pulsante destro del mouse sul nome del progetto nel Esplora soluzioni e scegliere di aggiungere un nuovo modulo Web denominato Default.aspx. Questa volta, selezionare la casella di controllo "Seleziona pagina master" e scegliere la pagina master Site.master dall'elenco.

Aggiungere una nuova pagina Default.aspx scelta per selezionare una pagina master

Figura 5: Aggiungere una nuova pagina Default.aspx scelta per selezionare una pagina master (fare clic per visualizzare un'immagine a dimensioni complete)

Usare la pagina master site.master

Figura 6: Usare la pagina master site.master

Nota

Se si usa il modello di progetto applicazione Web, la finestra di dialogo Aggiungi nuovo elemento non include una casella di controllo "Seleziona pagina master". È invece necessario aggiungere un elemento di tipo "Modulo contenuto Web". Dopo aver scelto l'opzione "Modulo contenuto Web" e fare clic su Aggiungi, Visual Studio visualizzerà la stessa finestra di dialogo Seleziona master visualizzata nella figura 6.

Il nuovo markup dichiarativo della pagina di Default.aspx include solo una direttiva che specifica il percorso del file di pagina master e un @Page controllo Contenuto per il contentplaceholder della pagina master.

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
</asp:Content>

Per il momento, lasciare vuoto Default.aspx. Verrà restituito più avanti in questa esercitazione per aggiungere contenuto.

Nota

La pagina master include una sezione per un menu o un'altra interfaccia di spostamento. Verrà creata tale interfaccia in un'esercitazione futura.

Passaggio 2: Abilitazione dell'autenticazione dei moduli

Con il sito Web ASP.NET creato, l'attività successiva consiste nell'abilitare l'autenticazione dei moduli. La configurazione di autenticazione dell'applicazione viene specificata tramite l'elemento<authentication> in Web.config. L'elemento <authentication> contiene un singolo attributo denominato mode che specifica il modello di autenticazione usato dall'applicazione. Questo attributo può avere uno dei quattro valori seguenti:

  • Windows: come illustrato nell'esercitazione precedente, quando un'applicazione usa autenticazione di Windows è responsabilità del server Web autenticare il visitatore e questa operazione viene in genere eseguita tramite Basic, Digest o Integrated autenticazione di Windows.
  • Moduli: gli utenti vengono autenticati tramite un modulo in una pagina Web.
  • Passport: gli utenti vengono autenticati tramite La rete Passport di Microsoft.
  • Nessuno: non viene usato alcun modello di autenticazione; tutti i visitatori sono anonimi.

Per impostazione predefinita, le applicazioni ASP.NET usano autenticazione di Windows. Per modificare il tipo di autenticazione in autenticazione form, è quindi necessario modificare l'attributo <authentication> mode dell'elemento in Forms.

Se il progetto non contiene ancora un file Web.config, aggiungerne uno facendo clic con il pulsante destro del mouse sul nome del progetto nella Esplora soluzioni, scegliendo Aggiungi nuovo elemento e quindi aggiungendo un file di configurazione Web.

Se il progetto non include ancora Web.config, aggiungerlo ora

Figura 7: se il progetto non include ancora Web.config, aggiungerlo ora (fare clic per visualizzare l'immagine full-size)

Individuare quindi l'elemento e aggiornarlo per usare l'autenticazione <authentication> dei moduli. Dopo questa modifica, il markup del file di Web.config dovrebbe essere simile al seguente:

<configuration>
    <system.web>
        ... Unrelated configuration settings and comments removed for brevity ...
        <!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
        -->
        <authentication mode="Forms" />
    </system.web>
</configuration>

Nota

Poiché Web.config è un file XML, la maiuscole e minuscole è importante. Assicurarsi di impostare l'attributo mode su Forms, con la maiuscola "F". Se si usa una combinazione di maiuscole e minuscole diverse, ad esempio "moduli", si riceverà un errore di configurazione durante la visita al sito tramite un browser.

L'elemento <authentication> può includere facoltativamente un <forms> elemento figlio che contiene impostazioni specifiche per l'autenticazione dei moduli. Per il momento, è sufficiente usare le impostazioni di autenticazione dei moduli predefinite. Si esaminerà l'elemento <forms> figlio in modo più dettagliato nell'esercitazione successiva.

Passaggio 3: Creazione della pagina di accesso

Per supportare l'autenticazione dei moduli, il sito Web necessita di una pagina di accesso. Come illustrato nella sezione "Understanding the Forms Authentication Workflow" (Informazioni sul flusso di lavoro di autenticazione form), l'utente FormsAuthenticationModule reindirizzerà automaticamente l'utente alla pagina di accesso se tenta di accedere a una pagina che non è autorizzata a visualizzare. Sono disponibili anche ASP.NET controlli Web che visualizzeranno un collegamento alla pagina di accesso agli utenti anonimi. Si tratta di una domanda: "Qual è l'URL della pagina di accesso?"

Per impostazione predefinita, il sistema di autenticazione dei moduli prevede che la pagina di accesso venga denominata Login.aspx e inserita nella directory radice dell'applicazione Web. Se si vuole usare un URL di pagina di accesso diverso, è possibile specificarlo in Web.config. Verrà illustrato come eseguire questa operazione nell'esercitazione successiva.

La pagina di accesso ha tre responsabilità:

  1. Fornire un'interfaccia che consente al visitatore di immettere le proprie credenziali.
  2. Determinare se le credenziali inviate sono valide.
  3. "Accedi" l'utente creando il ticket di autenticazione dei moduli.

Creazione dell'interfaccia utente della pagina di accesso

Iniziamo con la prima attività. Aggiungere una nuova pagina ASP.NET alla directory radice del sito denominata Login.aspx e associarla alla pagina master Site.master.

Aggiungere una nuova pagina ASP.NET denominata Login.aspx

Figura 8: Aggiungere una nuova pagina ASP.NET denominata Login.aspx (fare clic per visualizzare l'immagine a dimensioni complete)

L'interfaccia tipica della pagina di accesso è costituita da due caselle di testo, una per il nome dell'utente, una per la password e un pulsante per inviare il modulo. I siti Web spesso includono una casella di controllo "Ricordami" che, se selezionata, mantiene il ticket di autenticazione risultante tra i riavvii del browser.

Aggiungere due Caselle di testo per Login.aspx e impostare rispettivamente le relative ID proprietà su UserName e Password. Impostare anche la TextMode proprietà password su Password. Aggiungere quindi un controllo CheckBox, impostandone la ID proprietà su RememberMe e sulla relativa Text proprietà su "Ricordami". In seguito, aggiungere un pulsante denominato LoginButton la cui Text proprietà è impostata su "Login". Infine, aggiungere un controllo Web Label e impostarne la ID proprietà su InvalidCredentialsMessage, la relativa Text proprietà su "Nome utente o password non è valida. Riprovare.", la ForeColor relativa proprietà su Red e la relativa Visible proprietà su False.

A questo punto la schermata dovrebbe essere simile alla schermata nella figura 9 e la sintassi dichiarativa della pagina dovrebbe essere simile alla seguente:

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
    <h1>
        Login</h1>
    <p>
        Username:
        <asp:TextBox ID="UserName" runat="server"></asp:TextBox></p>
    <p>
        Password:
        <asp:TextBox ID="Password" runat="server" TextMode="Password"></asp:TextBox></p>
    <p>
        <asp:CheckBox ID="RememberMe" runat="server" Text="Remember Me" /> </p>
    <p>
        <asp:Button ID="LoginButton" runat="server" Text="Login" OnClick="LoginButton_Click" /> </p>
    <p>
        <asp:Label ID="InvalidCredentialsMessage" runat="server" ForeColor="Red" Text="Your username or password is invalid. Please try again."
            Visible="False"></asp:Label> </p>
</asp:Content>

La pagina di accesso contiene due caselle di testo, una casella di controllo, un pulsante e un'etichetta

Figura 9: la pagina di accesso contiene due caselle di testo, una casella di controllo, un pulsante e un'etichetta (fare clic per visualizzare un'immagine full-size)

Infine, creare un gestore eventi per l'evento Click di LoginButton. Dal Designer, fare doppio clic sul controllo Pulsante per creare questo gestore eventi.

Determinazione se le credenziali specificate sono valide

È ora necessario implementare l'attività 2 nel gestore eventi Click del pulsante, determinando se le credenziali specificate sono valide. Per eseguire questa operazione, è necessario disporre di un archivio utenti che contiene tutte le credenziali degli utenti in modo che sia possibile determinare se le credenziali specificate corrispondono a tutte le credenziali note.

Prima di ASP.NET 2.0, gli sviluppatori erano responsabili dell'implementazione sia degli archivi utente che della scrittura del codice per convalidare le credenziali fornite dall'archivio. La maggior parte degli sviluppatori implementerebbe l'archivio utenti in un database, creando una tabella denominata Utenti con colonne come UserName, Password, Email, LastLoginDate e così via. Questa tabella, quindi, avrebbe un record per account utente. La verifica delle credenziali fornite da un utente comporta l'esecuzione di query sul database per un nome utente corrispondente e quindi verificare che la password nel database corrisponda alla password specificata.

Con ASP.NET 2.0, gli sviluppatori devono usare uno dei provider di appartenenza per gestire l'archivio utenti. In questa serie di esercitazioni verrà usato SqlMembershipProvider, che usa un database SQL Server per l'archivio utenti. Quando si usa SqlMembershipProvider, è necessario implementare uno schema di database specifico che include le tabelle, le visualizzazioni e le stored procedure previste dal provider. Verrà illustrato come implementare questo schema nell'esercitazione Creazione dello schema di appartenenza in SQL Server. Con il provider di appartenenza, convalidare le credenziali dell'utente è semplice come chiamare il metodo ValidateUser(username, password) della classe Membership, che restituisce un valore booleano che indica se la validità della combinazione di nome utente e password. Poiché non è ancora stato implementato l'archivio utenti di SqlMembershipProvider, non è possibile usare il metodo ValidateUser della classe Membership in questo momento.

Invece di dedicare il tempo necessario per compilare la tabella di database Users personalizzata (che sarebbe obsoleta dopo l'implementazione di SqlMembershipProvider), è invece necessario impostare come hardcoded le credenziali valide all'interno della pagina di accesso stessa. Nel gestore eventi Click di LoginButton aggiungere il codice seguente:

protected void LoginButton_Click(object sender, EventArgs e)
{
    // Three valid username/password pairs: Scott/password, Jisun/password, and Sam/password.
    string[] users = { "Scott", "Jisun", "Sam" };
    string[] passwords = { "password", "password", "password" };
    for (int i = 0; i < users.Length; i++)
    {
        bool validUsername = (string.Compare(UserName.Text, users[i], true) == 0);
        bool validPassword = (string.Compare(Password.Text, passwords[i], false) == 0);
        if (validUsername && validPassword)
        {
            // TODO: Log in the user...
            // TODO: Redirect them to the appropriate page
        }
    }
    // If we reach here, the user's credentials were invalid
    InvalidCredentialsMessage.Visible = true;
}

Come si può notare, sono disponibili tre account utente validi, Scott, Jisun e Sam, e tutti e tre hanno la stessa password ("password"). Il codice esegue un ciclo tra gli utenti e le matrici di password che cercano una corrispondenza valida di nome utente e password. Se sia il nome utente che la password sono validi, è necessario accedere all'utente e quindi reindirizzarli alla pagina appropriata. Se le credenziali non sono valide, viene visualizzata l'etichetta InvalidCredentialsMessage.

Quando un utente immette credenziali valide, ho indicato che vengono reindirizzate alla "pagina appropriata". Qual è però la pagina appropriata? Tenere presente che quando un utente visita una pagina che non è autorizzata a visualizzare, FormsAuthenticationModule li reindirizza automaticamente alla pagina di accesso. In questo modo, include l'URL richiesto nella stringa di query tramite il parametro ReturnUrl. Ovvero, se un utente ha tentato di visitare ProtectedPage.aspx e non è stato autorizzato a farlo, FormsAuthenticationModule li reindirizzerà a:

Aspx? ReturnUrl=ProtectedPage.aspx

Al termine dell'accesso, l'utente deve essere reindirizzato a ProtectedPage.aspx. In alternativa, gli utenti possono visitare la pagina di accesso autonomamente. In tal caso, dopo l'accesso all'utente, deve essere inviato alla pagina di Default.aspx della cartella radice.

Accesso all'utente

Supponendo che le credenziali fornite siano valide, è necessario creare un ticket di autenticazione basata su form, quindi accedere all'utente al sito. La classe FormsAuthentication nello spazio dei nomi System.Web.Security fornisce metodi diversi per l'accesso e la disconnessione degli utenti tramite il sistema di autenticazione basata su form. Anche se nella classe FormsAuthentication sono disponibili diversi metodi, i tre sono interessati a questo punto:

  • GetAuthCookie(username, persistCookie): crea un ticket di autenticazione basata su form per il nome utente specificato. Successivamente, questo metodo crea e restituisce un oggetto HttpCookie che contiene il contenuto del ticket di autenticazione. Se persistCookie è true, viene creato un cookie permanente.
  • SetAuthCookie(username, persistCookie): chiama il metodo GetAuthCookie(username, persistCookie) per generare il cookie di autenticazione basata su form. Questo metodo aggiunge quindi il cookie restituito da GetAuthCookie alla raccolta Cookies (presupponendo che venga usata l'autenticazione basata su cookie; in caso contrario, questo metodo chiama una classe interna che gestisce la logica del ticket senza cookie).
  • RedirectFromLoginPage(username, persistCookie): questo metodo chiama SetAuthCookie(username, persistCookie) e quindi reindirizza l'utente alla pagina appropriata.

GetAuthCookie è utile quando è necessario modificare il ticket di autenticazione prima di scrivere il cookie nella raccolta Cookies. SetAuthCookie è utile se si vuole creare il ticket di autenticazione dei moduli e aggiungerlo alla raccolta Cookies, ma non si vuole reindirizzare l'utente alla pagina appropriata. È possibile conservarli nella pagina di accesso o inviarli a una pagina alternativa.

Poiché si vuole accedere all'utente e reindirizzarli alla pagina appropriata, si userà RedirectFromLoginPage. Aggiornare il gestore eventi Click di LoginButton, sostituendo le due righe TODO commentate con la riga di codice seguente:

FormsAuthentication.RedirectFromLoginPage(UserName.Text, RememberMe.Checked);

Quando si crea il ticket di autenticazione basata su form, si usa la proprietà TextBox userName per il parametro nome utente del ticket di autenticazione basata su form e lo stato selezionato del controllo CheckBox RememberMe per il parametro persistCookie .

Per testare la pagina di accesso, visitare la pagina in un browser. Per iniziare, immettere credenziali non valide, ad esempio un nome utente "Nope" e una password "sbagliata". Facendo clic sul pulsante Login verrà eseguito un postback e verrà visualizzata l'etichetta InvalidCredentialsMessage.

L'etichetta InvalidCredentialsMessage viene visualizzata quando si immettono credenziali non valide

Figura 10: L'etichetta InvalidCredentialsMessage viene visualizzata quando si immettono credenziali non valide (fare clic per visualizzare l'immagine a dimensione intera)

Immettere quindi credenziali valide e fare clic sul pulsante Accedi. Questa volta che si verifica il postback viene creato un ticket di autenticazione basata su form e si viene reindirizzati automaticamente a Default.aspx. A questo punto è stato effettuato l'accesso al sito Web, anche se non sono presenti segnali visivi per indicare che si è attualmente connessi. Nel passaggio 4 verrà illustrato come determinare a livello di codice se un utente è connesso o meno e come identificare l'utente che visita la pagina.

Il passaggio 5 esamina le tecniche per la registrazione di un utente dal sito Web.

Protezione della pagina di accesso

Quando l'utente immette le credenziali e invia il modulo della pagina di accesso, le credenziali, inclusa la password, vengono trasmesse tramite Internet al server Web in testo normale. Ciò significa che qualsiasi hacker che analizza il traffico di rete può visualizzare il nome utente e la password. Per evitare questo problema, è essenziale crittografare il traffico di rete usando Secure Socket Layers (SSL). In questo modo si garantisce che le credenziali (nonché il markup HTML dell'intera pagina) vengano crittografate dal momento in cui lasciano il browser fino a quando non vengono ricevute dal server Web.

A meno che il sito Web non contenga informazioni riservate, sarà necessario usare SSL solo nella pagina di accesso e in altre pagine in cui la password dell'utente verrebbe altrimenti inviata in transito in testo normale. Non è necessario preoccuparsi di proteggere il ticket di autenticazione basata su form perché, per impostazione predefinita, è crittografato e firmato digitalmente (per evitare manomissioni). Nell'esercitazione seguente viene presentata una discussione più approfondita sulla sicurezza dei ticket di autenticazione basata su moduli.

Nota

Molti siti Web finanziari e medici sono configurati per l'uso di SSL in tutte le pagine accessibili agli utenti autenticati. Se si sta creando un sito Web di questo tipo, è possibile configurare il sistema di autenticazione basata su form in modo che il ticket di autenticazione dei moduli venga trasmesso solo tramite una connessione sicura.

Passaggio 4: Rilevare i visitatori autenticati e determinare la propria identità

A questo punto è stata abilitata l'autenticazione basata su moduli e è stata creata una pagina di accesso rudimentale, ma è ancora necessario esaminare come è possibile determinare se un utente è autenticato o anonimo. In alcuni scenari potrebbe essere opportuno visualizzare dati o informazioni diversi a seconda che un utente autenticato o anonimo visiti la pagina. Inoltre, spesso è necessario conoscere l'identità dell'utente autenticato.

È possibile aumentare la pagina di Default.aspx esistente per illustrare queste tecniche. In Default.aspx aggiungere due controlli Panel, uno denominato AuthenticatedMessagePanel e un altro denominato AnonymousMessagePanel. Aggiungere un controllo Label denominato WelcomeBackMessage nel primo pannello. Nel secondo pannello aggiungere un controllo HyperLink, impostarne la proprietà Text su "Log In" e la relativa proprietà NavigateUrl su "~/Login.aspx". A questo punto il markup dichiarativo per Default.aspx dovrebbe essere simile al seguente:

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
    <asp:Panel runat="server" ID="AuthenticatedMessagePanel">
        <asp:Label runat="server" ID="WelcomeBackMessage"></asp:Label>
    </asp:Panel>
    
    <asp:Panel runat="Server" ID="AnonymousMessagePanel">
        <asp:HyperLink runat="server" ID="lnkLogin" Text="Log In" NavigateUrl="~/Login.aspx"></asp:HyperLink>
    </asp:Panel>
</asp:Content>

Come probabilmente hai probabilmente indovinato da ora, l'idea è quella di visualizzare solo AuthenticatedMessagePanel per autenticare i visitatori e solo AnonymousMessagePanel per i visitatori anonimi. A tale scopo, è necessario impostare le proprietà Visible di questi pannelli a seconda che l'utente sia connesso o meno.

La proprietà Request.IsAuthenticated restituisce un valore booleano che indica se la richiesta è stata autenticata. Immettere il codice seguente nel codice del gestore eventi Page_Load:

protected void Page_Load(object sender, EventArgs e)
{
    if (Request.IsAuthenticated)
    {
        WelcomeBackMessage.Text = "Welcome back!";
    
        AuthenticatedMessagePanel.Visible = true;
        AnonymousMessagePanel.Visible = false;
    }
    else
    {
        AuthenticatedMessagePanel.Visible = false;
        AnonymousMessagePanel.Visible = true;
    }
}

Con questo codice sul posto, visitare Default.aspx tramite un browser. Supponendo che sia ancora necessario accedere, verrà visualizzato un collegamento alla pagina di accesso (vedere la figura 11). Fare clic su questo collegamento e accedere al sito. Come illustrato nel passaggio 3, dopo aver immesso le credenziali verrà restituito a Default.aspx, ma questa volta la pagina mostra il messaggio "Welcome back!" (vedere la figura 12).

Quando si visita in modo anonimo, viene visualizzato un collegamento di accesso

Figura 11: Quando si visita in modo anonimo, viene visualizzato un collegamento di accesso

Gli utenti autenticati vengono visualizzati

Figura 12: Gli utenti autenticati vengono visualizzati come "Benvenuti!" Messaggio

È possibile determinare l'identità dell'utente attualmente connesso tramite la proprietà Userdell'oggetto HttpContext. L'oggetto HttpContext rappresenta informazioni sulla richiesta corrente ed è la home page di oggetti comuni ASP.NET come Risposta, Richiesta e Sessione, tra gli altri. La proprietà User rappresenta il contesto di sicurezza della richiesta HTTP corrente e implementa l'interfaccia IPrincipal.

La proprietà User viene impostata da FormsAuthenticationModule. In particolare, quando FormsAuthenticationModule trova un ticket di autenticazione basata su form nella richiesta in ingresso, crea un nuovo oggetto GenericPrincipal e lo assegna alla proprietà User.

Gli oggetti Principal (ad esempio GenericPrincipal) forniscono informazioni sull'identità dell'utente e sui ruoli a cui appartengono. L'interfaccia IPrincipal definisce due membri:

È possibile determinare il nome del visitatore corrente usando il codice seguente:

string currentUsersName = User.Identity.Name;

Quando si usa l'autenticazione basata su form, viene creato un oggetto FormsIdentity per la proprietà Identity di GenericPrincipal. La classe FormsIdentity restituisce sempre la stringa "Forms" per la proprietà AuthenticationType e true per la relativa proprietà IsAuthenticated. La proprietà Name restituisce il nome utente specificato durante la creazione del ticket di autenticazione basata su form. Oltre a queste tre proprietà, FormsIdentity include l'accesso al ticket di autenticazione sottostante tramite la relativa proprietà Ticket. La proprietà Ticket restituisce un oggetto di tipo FormsAuthenticationTicket, che dispone di proprietà come Expiration, IsPersistent, IssueDate, Name e così via.

Il punto importante da tenere presente è che il parametro username specificato nei metodi FormsAuthentication.GetAuthCookie(username, persistCookie), FormsAuthentication.SetAuthCookie(username, persistCookie) e FormsAuthentication.RedirectFromLoginPage(username, persistCookie) è lo stesso valore restituito da User.Identity.Name. Inoltre, il ticket di autenticazione creato da questi metodi è disponibile eseguendo il cast di User.Identity a un oggetto FormsIdentity e quindi accedendo alla proprietà Ticket:

FormsIdentity ident = User.Identity as FormsIdentity;
FormsAuthenticationTicket authTicket = ident.Ticket;

Fornire un messaggio più personalizzato in Default.aspx. Aggiornare il gestore eventi Page_Load in modo che alla proprietà Text dell'etichetta WelcomeBackMessage sia assegnata la stringa "Welcome back, username!"

WelcomeBackMessage.Text = "Welcome back, " + User.Identity.Name + "!";

La figura 13 mostra l'effetto di questa modifica (quando si accede come utente Scott).

Il messaggio di benvenuto include il nome dell'utente attualmente connesso

Figura 13: Il messaggio di benvenuto include il nome dell'utente attualmente connesso

Uso dei controlli LoginView e LoginName

La visualizzazione di contenuti diversi per gli utenti autenticati e anonimi è un requisito comune; quindi viene visualizzato il nome dell'utente attualmente connesso. Per questo motivo, ASP.NET include due controlli Web che forniscono la stessa funzionalità illustrata nella figura 13, ma senza la necessità di scrivere una singola riga di codice.

Il controllo LoginView è un controllo Web basato su modelli che semplifica la visualizzazione di dati diversi per gli utenti autenticati e anonimi. LoginView include due modelli predefiniti:

  • AnonymousTemplate: qualsiasi markup aggiunto a questo modello viene visualizzato solo ai visitatori anonimi.
  • LoggedInTemplate: il markup di questo modello viene visualizzato solo per gli utenti autenticati.

Aggiungiamo il controllo LoginView alla pagina master del sito, Site.master. Invece di aggiungere solo il controllo LoginView, è necessario aggiungere sia un nuovo controllo ContentPlaceHolder che quindi inserire il controllo LoginView all'interno del nuovo ContentPlaceHolder. La razionalità di questa decisione diventerà evidente a breve.

Nota

Oltre a AnonymousTemplate e LoggedInTemplate, il controllo LoginView può includere modelli specifici del ruolo. I modelli specifici del ruolo mostrano il markup solo a quelli che appartengono a un ruolo specificato. Verranno esaminate le funzionalità basate sul ruolo del controllo LoginView in un'esercitazione futura.

Iniziare aggiungendo un ContentPlaceHolder denominato LoginContent nella pagina master all'interno dell'elemento div> di spostamento<. È sufficiente trascinare un controllo ContentPlaceHolder dalla casella degli strumenti nella visualizzazione Origine, posizionando il markup risultante sopra "TODO: menu verrà visualizzato qui..." Testo.

<div id="navigation">
    <asp:ContentPlaceHolder ID="LoginContent" runat="server">
    </asp:ContentPlaceHolder>
   
    TODO: Menu will go here...
</div>

Aggiungere quindi un controllo LoginView all'interno di LoginContent ContentPlaceHolder. Il contenuto inserito nei controlli ContentPlaceHolder della pagina master è considerato contenuto predefinito per ContentPlaceHolder. Vale a dire, ASP.NET pagine che usano questa pagina master possono specificare il proprio contenuto per ogni ContentPlaceHolder o usare il contenuto predefinito della pagina master.

LoginView e altri controlli correlati all'account di accesso si trovano nella scheda Account di accesso della casella degli strumenti.

Controllo LoginView nella casella degli strumenti

Figura 14: Controllo LoginView nella casella degli strumenti

Aggiungere quindi due <br/> elementi immediatamente dopo il controllo LoginView, ma ancora all'interno del ContentPlaceHolder. A questo punto, il markup dell'elemento div> di spostamento <dovrebbe essere simile al seguente:

<div id="navigation">
    <asp:ContentPlaceHolder ID="LoginContent" runat="server">
        <asp:LoginView ID="LoginView1" runat="server">
        </asp:LoginView>
        <br /><br />
    </asp:ContentPlaceHolder>
   
    TODO: Menu will go here...
</div>

I modelli di LoginView possono essere definiti dal Designer o dal markup dichiarativo. Dall'Designer di Visual Studio espandere lo smart tag di LoginView, che elenca i modelli configurati in un elenco a discesa. Digitare il testo "Hello, stranger" in AnonymousTemplate; aggiungere quindi un controllo HyperLink e impostare rispettivamente le proprietà Text e NavigateUrl su "Log In" e "~/Login.aspx".

Dopo aver configurato AnonymousTemplate, passare a LoggedInTemplate e immettere il testo "Welcome back, ". Trascinare quindi un controllo LoginName dalla casella degli strumenti nel testo LoggedInTemplate, posizionandolo immediatamente dopo il testo "Welcome back". Il controllo LoginName, come indica il nome, visualizza il nome dell'utente attualmente connesso. Internamente, il controllo LoginName restituisce semplicemente la proprietà User.Identity.Name

Dopo aver effettuato queste aggiunte ai modelli di LoginView, il markup dovrebbe essere simile al seguente:

<div id="navigation">
    <asp:ContentPlaceHolder ID="LoginContent" runat="server">
        <asp:LoginView ID="LoginView1" runat="server">
            <LoggedInTemplate>
                Welcome back,
                <asp:LoginName ID="LoginName1" runat="server" />.
            </LoggedInTemplate>
            <AnonymousTemplate>
                Hello, stranger.
                <asp:HyperLink ID="lnkLogin" runat="server" NavigateUrl="~/Login.aspx">Log In</asp:HyperLink>
            </AnonymousTemplate>
        </asp:LoginView>
        
        <br /><br />
    </asp:ContentPlaceHolder>
   
    TODO: Menu will go here...
</div>

Con questa aggiunta alla pagina master Site.master, ogni pagina del sito Web visualizzerà un messaggio diverso a seconda che l'utente sia autenticato. La figura 15 mostra la pagina Default.aspx quando viene visitata tramite un browser da parte dell'utente Jisun. Il messaggio "Welcome back, Jisun" viene ripetuto due volte: una volta nella sezione di spostamento della pagina master a sinistra (tramite il controllo LoginView appena aggiunto) e una volta nell'area contenuto dell'Default.aspx (tramite i controlli Pannello e la logica programmatica).

Viene visualizzato il controllo LoginView

Figura 15: il controllo LoginView visualizza "Benvenuti, Jisun".

Poiché è stato aggiunto LoginView alla pagina master, può essere visualizzato in ogni pagina del sito. Tuttavia, potrebbero essere presenti pagine Web in cui non si vuole visualizzare questo messaggio. Una pagina di questo tipo è la pagina di accesso, poiché un collegamento alla pagina di accesso sembra fuori luogo. Poiché è stato inserito il controllo LoginView in un ContentPlaceHolder nella pagina master, è possibile eseguire l'override di questo markup predefinito nella pagina del contenuto. Aprire Login.aspx e passare alla Designer. Poiché non è stato definito in modo esplicito un controllo Contenuto in Login.aspx per loginContent ContentPlaceHolder nella pagina master, la pagina di accesso mostrerà il markup predefinito della pagina master per questo ContentPlaceHolder. È possibile visualizzare questa operazione tramite l'Designer: loginContent ContentPlaceHolder mostra il markup predefinito (controllo LoginView).

La pagina account di accesso mostra il contenuto predefinito per il contenuto della pagina master LoginContent ContentPlaceHolder

Figura 16: la pagina di accesso mostra il contenuto predefinito per il ContentPlaceHolder della pagina master (fare clic per visualizzare l'immagine full-size)

Per eseguire l'override del markup predefinito per LoginContent ContentPlaceHolder, fare semplicemente clic con il pulsante destro del mouse sull'area nella Designer e scegliere l'opzione Crea contenuto personalizzato dal menu di scelta rapida. Quando si usa Visual Studio 2008, ContentPlaceHolder include uno smart tag che, quando selezionato, offre la stessa opzione. Questo aggiunge un nuovo controllo Contenuto al markup della pagina e consente di definire contenuto personalizzato per questa pagina. È possibile aggiungere un messaggio personalizzato qui, ad esempio "Accedere...", ma è sufficiente lasciare vuoto questo messaggio.

Nota

In Visual Studio 2005 la creazione di contenuto personalizzato crea un controllo Contenuto vuoto nella pagina ASP.NET. In Visual Studio 2008, tuttavia, la creazione di contenuti personalizzati copia il contenuto predefinito della pagina master nel controllo Contenuto appena creato. Se si usa Visual Studio 2008, dopo aver creato il nuovo controllo Contenuto, assicurarsi di cancellare il contenuto copiato dalla pagina master.

La figura 17 mostra la pagina Login.aspx quando viene visitata da un browser dopo aver apportato questa modifica. Si noti che non c'è alcun messaggio "Hello, stranger" o "Welcome back, username" nel div> di spostamento <sinistro perché c'è quando si visita Default.aspx.

La pagina di accesso nasconde il markup del contenuto LoginContent ContentPlaceHolder predefinito

Figura 17: la pagina di accesso nasconde il markup del contenuto LoginContent ContentPlaceHolder predefinito (fare clic per visualizzare l'immagine full-size)

Passaggio 5: Disconnessione

Nel passaggio 3 è stato esaminato come creare una pagina di accesso per accedere a un utente nel sito, ma è ancora necessario vedere come disconnettere un utente. Oltre ai metodi per la registrazione di un utente in, la classe FormsAuthentication fornisce anche un metodo SignOut. Il metodo SignOut elimina semplicemente il ticket di autenticazione dei moduli, registrando così l'utente fuori dal sito.

L'offerta di un collegamento di disconnessione è una funzionalità comune che ASP.NET include un controllo progettato in modo specifico per disconnettere un utente. Il controllo LoginStatus visualizza un linkButton "Login" o un linkButton "Logout", a seconda dello stato di autenticazione dell'utente. Viene eseguito il rendering di un linkButton "Login" per gli utenti anonimi, mentre viene visualizzato un linkButton "Logout" per gli utenti autenticati. Il testo per "Login" e "Logout" LinkButtons può essere configurato tramite le proprietà LoginStatus e LogoutText.

Facendo clic sul collegamento "Login" LinkButton viene generato un postback, da cui viene emesso un reindirizzamento alla pagina di accesso. Facendo clic sul collegamento "Disconnessione" LinkButton il controllo LoginStatus richiama il metodo FormsAuthentication.SignOff e quindi reindirizza l'utente a una pagina. La pagina in cui l'utente connesso viene reindirizzato a dipende dalla proprietà LogoutAction, che può essere assegnata a uno dei tre valori seguenti:

  • Aggiorna: impostazione predefinita; reindirizza l'utente alla pagina appena visitata. Se la pagina appena visitata non consente utenti anonimi, FormsAuthenticationModule reindirizzerà automaticamente l'utente alla pagina di accesso.

Potresti essere curioso del motivo per cui viene eseguito un reindirizzamento qui. Se l'utente vuole rimanere nella stessa pagina, perché la necessità del reindirizzamento esplicito? Il motivo è dovuto al fatto che quando viene fatto clic su "Logoff" LinkButton, l'utente ha ancora il ticket di autenticazione dei moduli nella raccolta dei cookie. Di conseguenza, la richiesta postback è una richiesta autenticata. Il controllo LoginStatus chiama il metodo SignOut, ma ciò avviene dopo l'autenticazione di FormsAuthenticationModule. Pertanto, un reindirizzamento esplicito fa sì che il browser richieda nuovamente la pagina. Al momento in cui il browser richiede nuovamente la pagina, il ticket di autenticazione dei moduli è stato rimosso e pertanto la richiesta in ingresso è anonima.

  • Reindirizzamento: l'utente viene reindirizzato all'URL specificato dalla proprietà LogoutPageUrl di LoginStatus.
  • RedirectToLoginPage: l'utente viene reindirizzato alla pagina di accesso.

Aggiungere un controllo LoginStatus alla pagina master e configurarlo per usare l'opzione Reindirizzamento per inviare l'utente a una pagina che visualizza un messaggio che conferma che sono stati disconnessi. Iniziare creando una pagina nella directory radice denominata Logout.aspx. Non dimenticare di associare questa pagina alla pagina master Site.master. Immettere quindi un messaggio nel markup della pagina che spiega all'utente che sono stati disconnessi.

Tornare quindi alla pagina master Site.master e aggiungere un controllo LoginStatus sotto loginView nel contenuto LoginContentPlaceHolder. Impostare la proprietà LogoutAction del controllo LoginStatus su Redirect e sulla relativa proprietà LogoutPageUrl su "~/Logout.aspx".

<div id="navigation">
    <asp:ContentPlaceHolder ID="LoginContent" runat="server">
        <asp:LoginView ID="LoginView1" runat="server">
            <LoggedInTemplate>
                Welcome back,
                <asp:LoginName ID="LoginName1" runat="server" />.
            </LoggedInTemplate>
            <AnonymousTemplate>
                Hello, stranger.
                <asp:HyperLink ID="lnkLogin" runat="server" NavigateUrl="~/Login.aspx">Log In</asp:HyperLink>
            </AnonymousTemplate>
        </asp:LoginView>
        <br />
        <asp:LoginStatus ID="LoginStatus1" runat="server" LogoutAction="Redirect" LogoutPageUrl="~/Logout.aspx" />
        
        <br /><br />
    </asp:ContentPlaceHolder>
   
    TODO: Menu will go here...
</div>

Poiché loginStatus è esterno al controllo LoginView, verrà visualizzato sia per gli utenti anonimi che autenticati, ma è OK perché LoginStatus visualizzerà correttamente un collegamento "Login" o "Logout". Con l'aggiunta del controllo LoginStatus, l'HyperLink "Log In" in AnonymousTemplate è superfluo, quindi rimuoverlo.

La figura 18 mostra Default.aspx quando Jisun visita. Si noti che la colonna sinistra visualizza il messaggio "Welcome back, Jisun" insieme a un collegamento per disconnettersi. Facendo clic sul log out LinkButton, viene eseguito un postback, si firma Jisun fuori dal sistema e quindi la reindirizza a Logout.aspx. Come illustrato nella figura 19, dal momento in cui Jisun raggiunge Logout.aspx è già stata disconnessa ed è quindi anonima. Di conseguenza, la colonna sinistra mostra il testo "Benvenuto, sconosciuto" e un collegamento alla pagina di accesso.

Default.aspx mostra

Figura 18: Default.aspx mostra "Welcome Back, Jisun" Insieme a un linkButton "Logout" (Fare clic per visualizzare l'immagine full-size)

Logout.aspx mostra

Figura 19: Logout.aspx Mostra "Benvenuto, sconosciuto" Insieme a un linkButton "Login" (Fare clic per visualizzare l'immagine full-size)

Nota

Ti consigliamo di personalizzare la pagina Logout.aspx per nascondere il ContentPlaceHolder della pagina master(come abbiamo fatto per Login.aspx nel passaggio 4). Il motivo è dovuto al fatto che il controllo "Login" LinkButton eseguito dal controllo LoginStatus (quello sotto "Hello, stranger") invia l'utente alla pagina di accesso passando l'URL corrente nel parametro ReturnUrl querystring. In breve, se un utente che ha eseguito l'accesso fa clic sul collegamento "Login" di LoginStatus e quindi accede, verrà reindirizzato a Logout.aspx, che potrebbe facilmente confondere l'utente.

Riepilogo

In questa esercitazione è stato avviato un esame del flusso di lavoro di autenticazione dei moduli e quindi è stato implementato l'autenticazione dei moduli in un'applicazione ASP.NET. L'autenticazione dei moduli è basata su FormsAuthenticationModule, che ha due responsabilità: identificare gli utenti in base al ticket di autenticazione dei moduli e reindirizzare utenti non autorizzati alla pagina di accesso.

La classe FormsAuthentication di .NET Framework include metodi per la creazione, l'ispezione e la rimozione dei ticket di autenticazione dei moduli. La proprietà Request.IsAuthenticated e l'oggetto User forniscono supporto programmatico aggiuntivo per determinare se una richiesta è autenticata e informazioni sull'identità dell'utente. Esistono anche i controlli Web LoginView, LoginStatus e LoginName, che consentono agli sviluppatori di eseguire molte attività comuni correlate all'accesso. Verranno esaminati questi controlli Web e altri controlli Web correlati all'accesso in modo più dettagliato nelle esercitazioni future.

Questa esercitazione ha fornito una panoramica cursore dell'autenticazione dei moduli. Non sono stati esaminate le opzioni di configurazione assortite, esaminare il funzionamento dei ticket di autenticazione dei moduli senza cookie o esplorare il modo in cui ASP.NET protegge il contenuto del ticket di autenticazione dei moduli.

Programmazione felice!

Altre informazioni

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

Training video sugli argomenti contenuti in questa esercitazione

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Microsoft Web dal 1998. Scott lavora come consulente indipendente, allenatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2,0 in 24 Ore. Può essere raggiunto a mitchell@4GuysFromRolla.com. o tramite il suo blog, che può essere trovato in http://ScottOnWriting.NET.

Grazie speciali a...

Questa serie di esercitazioni è stata esaminata da molti revisori utili. Il revisore lead per questa esercitazione è stato esaminato da molti revisori utili. I revisori principali per questa esercitazione includono Alicja Maziarz, John Suru e Teresa Murphy. Interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com.