Übersicht über die Formularauthentifizierung (C#)

von Scott Mitchell

Hinweis

Seit diesem Artikel wurden die ASP.NET-Mitgliedschaftsanbieter von ASP.NET Identity abgelöst. Es wird dringend empfohlen, Apps so zu aktualisieren, dass sie die ASP.NET Identity-Plattform anstelle der Mitgliedschaftsanbieter verwenden, die zum Zeitpunkt des Schreibens dieses Artikels vorgestellt wurden. ASP.NET Identity bietet eine Reihe von Vorteilen gegenüber dem ASP.NET Mitgliedschaftssystem, darunter:

  • Bessere Leistung
  • Verbesserte Erweiterbarkeit und Testbarkeit
  • Unterstützung für OAuth, OpenID Connect und zweistufige Authentifizierung
  • Unterstützung der anspruchsbasierten Identität
  • Bessere Interoperabilität mit ASP.Net Core

Code herunterladen oder PDF herunterladen

In diesem Tutorial werden wir von der reinen Diskussion zur Implementierung wechseln. insbesondere wird die Implementierung der Formularauthentifizierung untersucht. Die Webanwendung, mit der wir in diesem Tutorial beginnen, wird in den nachfolgenden Tutorials weiter aufgebaut, wenn wir von der einfachen Formularauthentifizierung zu Mitgliedschaft und Rollen wechseln.

Weitere Informationen zu diesem Thema finden Sie in diesem Video: Verwenden der Standardformularauthentifizierung in ASP.NET.

Einführung

Im vorherigen Tutorial haben wir die verschiedenen Authentifizierungs-, Autorisierungs- und Benutzerkontooptionen erläutert, die von ASP.NET bereitgestellt werden. In diesem Tutorial werden wir von der reinen Diskussion zur Implementierung wechseln. insbesondere wird die Implementierung der Formularauthentifizierung untersucht. Die Webanwendung, mit der wir in diesem Tutorial beginnen, wird in den nachfolgenden Tutorials weiter aufgebaut, wenn wir von der einfachen Formularauthentifizierung zu Mitgliedschaft und Rollen wechseln.

Dieses Tutorial beginnt mit einem ausführlichen Blick auf den Workflow für die Formularauthentifizierung, ein Thema, das wir im vorherigen Tutorial behandelt haben. Anschließend erstellen wir eine ASP.NET Website, über die die Konzepte der Formularauthentifizierung veranschaulicht werden können. Als Nächstes konfigurieren wir die Website für die Verwendung der Formularauthentifizierung, erstellen eine einfache Anmeldeseite und sehen, wie sie im Code ermitteln, ob ein Benutzer authentifiziert ist und, falls ja, den Benutzernamen, mit dem er sich angemeldet hat.

Das Verständnis des Formularauthentifizierungsworkflows, dessen Aktivierung in einer Webanwendung und das Erstellen der Anmelde- und Abmeldeseiten sind wichtige Schritte beim Erstellen einer ASP.NET-Anwendung, die Benutzerkonten unterstützt und Benutzer über eine Webseite authentifiziert. Aus diesem Und weil diese Tutorials aufeinander aufbauen, würde ich Sie ermutigen, dieses Tutorial vollständig durchzuarbeiten, bevor Sie mit dem nächsten Tutorial fortfahren, auch wenn Sie bereits Erfahrung beim Konfigurieren der Formularauthentifizierung in früheren Projekten hatten.

Grundlegendes zum Formularauthentifizierungsworkflow

Wenn die ASP.NET Runtime eine Anforderung für eine ASP.NET Ressource verarbeitet, z. B. eine ASP.NET Seite oder ASP.NET Webdienst, löst die Anforderung während ihres Lebenszyklus eine Reihe von Ereignissen aus. Es gibt Ereignisse, die ganz am Anfang und am Ende der Anforderung ausgelöst werden, solche, die ausgelöst werden, wenn die Anforderung authentifiziert und autorisiert wird, ein Ereignis, das im Fall einer nicht behandelten Ausnahme ausgelöst wird usw. Eine vollständige Auflistung der Ereignisse finden Sie unter Ereignisse des HttpApplication-Objekts.

HTTP-Module sind verwaltete Klassen, deren Code als Reaktion auf ein bestimmtes Ereignis im Anforderungslebenszyklus ausgeführt wird. ASP.NET wird mit einer Reihe von HTTP-Modulen ausgeliefert, die wichtige Aufgaben im Hintergrund ausführen. Zwei integrierte HTTP-Module, die für unsere Diskussion besonders relevant sind:

  • FormsAuthenticationModule – authentifiziert den Benutzer, indem das Formularauthentifizierungsticket überprüft wird, das in der Regel in der Cookiessammlung des Benutzers enthalten ist. Wenn kein Formularauthentifizierungsticket vorhanden ist, ist der Benutzer anonym.
  • UrlAuthorizationModule – bestimmt, ob der aktuelle Benutzer für den Zugriff auf die angeforderte URL autorisiert ist. Dieses Modul bestimmt die Autorität, indem die Autorisierungsregeln in den Konfigurationsdateien der Anwendung verwendet werden. ASP.NET umfasst auch das, das die FileAuthorizationModule Autorität bestimmt, indem die angeforderten Datei-ACLs abgerufen werden.

Der FormsAuthenticationModule versucht, den Benutzer vor der UrlAuthorizationModule Ausführung (und FileAuthorizationModule) zu authentifizieren. Wenn der Benutzer, der die Anforderung stellt, nicht für den Zugriff auf die angeforderte Ressource autorisiert ist, beendet das Autorisierungsmodul die Anforderung und gibt eine http 401 Nicht autorisierte status zurück. In Windows-Authentifizierung Szenarien wird die HTTP 401-status an den Browser zurückgegeben. Dieser status Code bewirkt, dass der Browser den Benutzer über ein modales Dialogfeld zur Eingabe seiner Anmeldeinformationen auffordert. Bei der Formularauthentifizierung wird die HTTP 401-nicht autorisierte status jedoch nie an den Browser gesendet, da formsAuthenticationModule diese status erkennt und ändert, um den Benutzer stattdessen zur Anmeldeseite umzuleiten (über einen HTTP 302-Umleitungs-status).

Die Aufgabe der Anmeldeseite besteht darin, zu ermitteln, ob die Anmeldeinformationen des Benutzers gültig sind, und wenn ja, ein Formularauthentifizierungsticket zu erstellen und den Benutzer zurück zu der Seite zu leiten, die er besuchen wollte. Das Authentifizierungsticket ist in nachfolgenden Anforderungen an die Seiten auf der Website enthalten, die zur FormsAuthenticationModule Identifizierung des Benutzers verwendet werden.

Der Formularauthentifizierungsworkflow

Abbildung 1: Formularauthentifizierungsworkflow

Erinnern des Authentifizierungstickets über Seitenbesuche hinweg

Nach der Anmeldung muss das Formularauthentifizierungsticket bei jeder Anforderung an den Webserver zurückgesendet werden, damit der Benutzer beim Durchsuchen der Website angemeldet bleibt. Dies wird in der Regel erreicht, indem das Authentifizierungsticket in der Cookiessammlung des Benutzers platziert wird. Cookies sind kleine Textdateien, die sich auf dem Computer des Benutzers befinden und in den HTTP-Headern bei jeder Anforderung an die Website übermittelt werden, die das Cookie erstellt hat. Sobald das Formularauthentifizierungsticket erstellt und in den Cookies des Browsers gespeichert wurde, sendet jeder nachfolgende Besuch dieser Website das Authentifizierungsticket zusammen mit der Anforderung, wodurch der Benutzer identifiziert wird.

Ein Aspekt von Cookies ist ihr Ablauf, d. h. das Datum und die Uhrzeit, an der der Browser das Cookie verwirft. Wenn das Formularauthentifizierungscooky abläuft, kann der Benutzer nicht mehr authentifiziert werden und wird daher anonym. Wenn ein Benutzer von einem öffentlichen Terminal aus besucht, besteht die Wahrscheinlichkeit, dass sein Authentifizierungsticket abläuft, wenn er seinen Browser schließt. Beim Besuch von zu Hause aus möchte derselbe Benutzer jedoch möglicherweise, dass das Authentifizierungsticket über Browserneustarts gespeichert wird, damit er sich nicht bei jedem Besuch der Website erneut anmelden muss. Diese Entscheidung trifft der Benutzer häufig in Form eines Kontrollkästchens "Remember me" auf der Anmeldeseite. In Schritt 3 wird untersucht, wie Sie auf der Anmeldeseite ein Kontrollkästchen "Erinnerung an mich" implementieren. Im folgenden Tutorial werden die Timeouteinstellungen für Authentifizierungstickets ausführlich behandelt.

Hinweis

Es ist möglich, dass der Für die Anmeldung auf der Website verwendete Benutzer-Agent cookies nicht unterstützt. In einem solchen Fall können ASP.NET cookieslose Formularauthentifizierungstickets verwenden. In diesem Modus wird das Authentifizierungsticket in die URL codiert. Im nächsten Tutorial wird erläutert, wann Tickets für die cookielose Authentifizierung verwendet werden und wie sie erstellt und verwaltet werden.

Der Bereich der Formularauthentifizierung

Der FormsAuthenticationModule ist verwalteter Code, der Teil der ASP.NET Runtime ist. Vor Version 7 des Iis-Webservers (Internet Information Services) von Microsoft gab es eine deutliche Barriere zwischen der HTTP-Pipeline von IIS und der Pipeline der ASP.NET Runtime. Kurz gesagt, in IIS 6 und früher wird nur ausgeführt FormsAuthenticationModule , wenn eine Anforderung von IIS an die ASP.NET Runtime delegiert wird. Standardmäßig verarbeitet IIS statische Inhalte selbst – z. B. HTML-Seiten, CSS- und Bilddateien – und gibt Anforderungen nur dann an die ASP.NET Runtime weiter, wenn eine Seite mit der Erweiterung .aspx, ASMX oder ASHX angefordert wird.

IIS 7 ermöglicht jedoch integrierte IIS- und ASP.NET-Pipelines. Mit einigen Konfigurationseinstellungen können Sie IIS 7 so einrichten, dass formsAuthenticationModule für alle Anforderungen aufgerufen wird. Darüber hinaus können Sie mit IIS 7 URL-Autorisierungsregeln für Dateien beliebiger Art definieren. Weitere Informationen finden Sie unter Änderungen zwischen IIS6- und IIS7-Sicherheit, Sicherheit Ihrer Webplattform und Grundlegendes zur IIS7-URL-Autorisierung.

Kurz gesagt, in Versionen vor IIS 7 können Sie nur die Formularauthentifizierung verwenden, um Ressourcen zu schützen, die von der ASP.NET Runtime verarbeitet werden. Ebenso werden URL-Autorisierungsregeln nur auf Ressourcen angewendet, die von der ASP.NET Runtime verarbeitet werden. Mit IIS 7 ist es jedoch möglich, formsAuthenticationModule und UrlAuthorizationModule in die HTTP-Pipeline von IIS zu integrieren, wodurch diese Funktionalität auf alle Anforderungen erweitert wird.

Schritt 1: Erstellen einer ASP.NET Website für diese Tutorialreihe

Um ein möglichst breites Publikum zu erreichen, wird die ASP.NET Website, die wir in dieser Reihe erstellen werden, mit der kostenlosen Version von Visual Studio 2008 von Microsoft erstellt, Visual Web Developer 2008. Wir implementieren den SqlMembershipProvider Benutzerspeicher in einer Microsoft SQL Server 2005 Express Edition-Datenbank. Wenn Sie Visual Studio 2005 oder eine andere Edition von Visual Studio 2008 oder SQL Server verwenden, machen Sie sich keine Sorgen: Die Schritte sind nahezu identisch, und es werden alle nicht trivialen Unterschiede hervorgehoben.

Hinweis

Die demo-Webanwendung, die in jedem Tutorial verwendet wird, steht als Download zur Verfügung. Diese herunterladbare Anwendung wurde mit Visual Web Developer 2008 für die .NET Framework Version 3.5 erstellt. Da die Anwendung auf .NET 3.5 ausgerichtet ist, enthält die Web.config-Datei zusätzliche 3.5-spezifische Konfigurationselemente. Kurz gesagt, wenn Sie .NET 3.5 noch auf Ihrem Computer installiert haben, funktioniert die herunterladbare Webanwendung nicht, ohne zuerst das 3.5-spezifische Markup aus Web.config zu entfernen.

Bevor wir die Formularauthentifizierung konfigurieren können, benötigen wir zunächst eine ASP.NET Website. Erstellen Sie zunächst eine neue dateisystembasierte ASP.NET Website. Starten Sie dazu Visual Web Developer, wechseln Sie zum Menü Datei, und wählen Sie Neue Website aus, und zeigen Sie das Dialogfeld Neue Website an. Wählen Sie die Vorlage ASP.NET Website aus, legen Sie die Dropdownliste Speicherort auf Dateisystem fest, wählen Sie einen Ordner aus, um die Website zu platzieren, und legen Sie die Sprache auf C# fest. Dadurch wird eine neue Website mit einer Default.aspx ASP.NET Seite, einem App_Data Ordner und einer Web.config-Datei erstellt.

Hinweis

Visual Studio unterstützt zwei Arten der Projektverwaltung: Websiteprojekte und Webanwendungsprojekte. Websiteprojekte haben keine Projektdatei, während Webanwendungsprojekte die Projektarchitektur in Visual Studio .NET 2002/2003 nachahmen– sie enthalten eine Projektdatei und kompilieren den Quellcode des Projekts in einer einzelnen Assembly, die sich im Ordner /bin befindet. Visual Studio 2005 unterstützte anfänglich nur Websiteprojekte, obwohl das Webanwendungsprojektmodell mit Service Pack 1 wieder eingeführt wurde. Visual Studio 2008 bietet beide Projektmodelle. Die Visual Web Developer 2005- und 2008-Editionen unterstützen jedoch nur Websiteprojekte. Ich verwende das Websiteprojektmodell. Wenn Sie eine Nicht-Express-Edition verwenden und stattdessen das Webanwendungsprojektmodell verwenden möchten, können Sie dies tun, aber beachten Sie, dass es möglicherweise Einige Abweichungen zwischen dem, was auf dem Bildschirm angezeigt wird, und den erforderlichen Schritten im Vergleich zu den in diesen Tutorials gezeigten Screenshots und Anweisungen gibt.

Erstellen einer neuen Datei System-Based Website

Abbildung 2: Erstellen einer neuen Datei System-Based Website (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Hinzufügen einer Gestaltungsvorlage

Fügen Sie als Nächstes der Website im Stammverzeichnis Site eine neue Gestaltungsvorlage hinzu. master. Gestaltungsvorlagen ermöglichen es einem Seitenentwickler, eine websiteweite Vorlage zu definieren, die auf ASP.NET Seiten angewendet werden kann. Der Standard Vorteil von master Seiten besteht darin, dass das Gesamtbild der Website an einem einzigen Ort definiert werden kann, wodurch das Layout der Website einfach aktualisiert oder optimiert werden kann.

Fügen Sie eine Gestaltungsvorlage mit dem Namen Website hinzu. master zur Website

Abbildung 3: Hinzufügen einer Gestaltungsvorlage mit dem Namen Website. master zur Website (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Definieren Sie das websiteweite Seitenlayout hier auf der master Seite. Sie können die Entwurfsansicht verwenden und alle benötigten Layout- oder Websteuerelemente hinzufügen, oder Sie können das Markup manuell in der Quellansicht hinzufügen. Ich habe das Layout meiner master Seite strukturiert, um das Layout nachzuahmen, das in meiner Tutorialreihe Arbeiten mit Daten in ASP.NET 2.0 verwendet wurde (siehe Abbildung 4). Die master Seite verwendet kaskadierende Stylesheets für die Positionierung und Stile mit den CSS-Einstellungen, die in der datei Style.css definiert sind (die im zugehörigen Download dieses Tutorials enthalten ist). Sie können das unten gezeigte Markup zwar nicht erkennen, aber die CSS-Regeln sind so definiert, dass der Inhalt des Navigations-DIV <>absolut positioniert ist, sodass er links angezeigt wird und eine feste Breite von 200 Pixel aufweist.

<%@ 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>

Eine master Seite definiert sowohl das statische Seitenlayout als auch die Regionen, die von den ASP.NET Seiten bearbeitet werden können, die die master Seite verwenden. Diese bearbeitbaren Inhaltsbereiche werden durch das ContentPlaceHolder Steuerelement angegeben, das in der Inhalts-DIV <>angezeigt werden kann. Unsere master Seite hat einen einzelnen ContentPlaceHolder (MainContent), aber master Seite kann mehrere ContentPlaceHolders aufweisen.

Wenn Sie das oben eingegebene Markup eingeben, zeigt der Wechsel zur Entwurfsansicht das Layout der master Seite an. Alle ASP.NET Seiten, die diese master Seite verwenden, verfügen über dieses einheitliche Layout mit der Möglichkeit, das Markup für die MainContent Region anzugeben.

Die Gestaltungsvorlage, wenn sie über die Entwurfsansicht angezeigt wird

Abbildung 4: Die Gestaltungsvorlage, wenn sie über die Entwurfsansicht angezeigt wird (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Erstellen von Inhaltsseiten

An diesem Punkt haben wir eine Default.aspx Seite auf unserer Website, aber sie verwendet nicht die master Seite, die wir gerade erstellt haben. Es ist zwar möglich, das deklarative Markup einer Webseite so zu bearbeiten, dass eine master Seite verwendet wird, aber wenn die Seite keinen Inhalt enthält, ist es einfacher, die Seite einfach zu löschen und dem Projekt erneut hinzuzufügen, wobei die master zu verwendende Seite angegeben wird. Löschen Sie daher zunächst Default.aspx aus dem Projekt.

Klicken Sie anschließend mit der rechten Maustaste auf den Projektnamen im Projektmappen-Explorer, und fügen Sie ein neues Webformular mit dem Namen Default.aspx hinzu. Aktivieren Sie dieses Mal das Kontrollkästchen "Master Seite auswählen", und wählen Sie Site.master master Seite aus der Liste.

Hinzufügen einer neuen Default.aspx Seite auswählen, um eine Gestaltungsvorlage auszuwählen

Abbildung 5: Hinzufügen eines neuen Default.aspx Seitenauswahl zum Auswählen einer Gestaltungsvorlage (Klicken, um das Bild in voller Größe anzuzeigen)

Verwenden Sie die Website. master Gestaltungsvorlage

Abbildung 6: Verwenden Sie die Website. master Gestaltungsvorlage

Hinweis

Wenn Sie das Webanwendungsprojektmodell verwenden, enthält das Dialogfeld Neues Element hinzufügen kein Kontrollkästchen "Master Seite auswählen". Stattdessen müssen Sie ein Element vom Typ "Webinhaltsformular" hinzufügen. Nachdem Sie die Option "Webinhaltsformular" ausgewählt und auf Hinzufügen geklickt haben, zeigt Visual Studio dasselbe Dialogfeld Master auswählen an, das in Abbildung 6 dargestellt ist.

Das deklarative Markup der neuen Default.aspx Seite enthält nur eine @Page Direktive, die den Pfad zur master Seitendatei angibt, und ein Content-Steuerelement für den MainContent ContentPlaceHolder der master Seite.

<%@ 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>

Lassen Sie vorerst Default.aspx leer. Wir kehren später in diesem Tutorial wieder darauf zurück, um Inhalte hinzuzufügen.

Hinweis

Unsere master Seite enthält einen Abschnitt für ein Menü oder eine andere Navigationsoberfläche. Wir werden eine solche Schnittstelle in einem zukünftigen Tutorial erstellen.

Schritt 2: Aktivieren der Formularauthentifizierung

Nachdem die ASP.NET Website erstellt wurde, besteht unsere nächste Aufgabe darin, die Formularauthentifizierung zu aktivieren. Die Authentifizierungskonfiguration der Anwendung wird über das <authentication> -Element in Web.config angegeben. Das <authentication> Element enthält ein einzelnes Attribut namens Mode, das das von der Anwendung verwendete Authentifizierungsmodell angibt. Dieses Attribut kann einen der folgenden vier Werte aufweisen:

  • Windows: Wie im vorherigen Tutorial erläutert, liegt es in der Verantwortung des Webservers, den Besucher zu authentifizieren, wenn eine Anwendung Windows-Authentifizierung verwendet, und dies geschieht in der Regel über Basic, Digest oder Integrated Windows-Authentifizierung.
  • Formulare: Benutzer werden über ein Formular auf einer Webseite authentifiziert.
  • Passport: Benutzer werden mithilfe des Passport-Netzwerks von Microsoft authentifiziert.
  • Keine: Es wird kein Authentifizierungsmodell verwendet. alle Besucher sind anonym.

Standardmäßig verwenden ASP.NET Anwendungen Windows-Authentifizierung. Um den Authentifizierungstyp in Formularauthentifizierung zu ändern, müssen wir dann das Mode-Attribut des <authentication> Elements in Forms ändern.

Wenn Ihr Projekt noch keine Web.config-Datei enthält, fügen Sie jetzt eine datei hinzu, indem Sie mit der rechten Maustaste auf den Projektnamen im Projektmappen-Explorer klicken, neues Element hinzufügen auswählen und dann eine Webkonfigurationsdatei hinzufügen.

Wenn Ihr Projekt noch nicht Web.config enthält, fügen Sie es jetzt hinzu.

Abbildung 7: Wenn Ihr Projekt noch keine Web.config enthält, fügen Sie es jetzt hinzu (Klicken Sie, um das bild in voller Größe anzuzeigen)

Suchen Sie als Nächstes nach dem <authentication> Element, und aktualisieren Sie es, um die Formularauthentifizierung zu verwenden. Nach dieser Änderung sollte das Markup Ihrer Web.config Datei wie folgt aussehen:

<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>

Hinweis

Da Web.config eine XML-Datei ist, ist die Groß- und Kleinschreibung wichtig. Stellen Sie sicher, dass Sie das Modus-Attribut auf Forms mit dem Großbuchstaben "F" festlegen. Wenn Sie eine andere Groß- und Kleinschreibung verwenden, z. B. "Forms", erhalten Sie einen Konfigurationsfehler, wenn Sie die Website über einen Browser besuchen.

Das <authentication> Element kann optional ein untergeordnetes <forms> Element enthalten, das formularauthentifizierungsspezifische Einstellungen enthält. Vorerst verwenden wir einfach die Standardeinstellungen für die Formularauthentifizierung. Im nächsten Tutorial werden wir das <forms> untergeordnete Element ausführlicher untersuchen.

Schritt 3: Erstellen der Anmeldeseite

Um die Formularauthentifizierung zu unterstützen, benötigt unsere Website eine Anmeldeseite. Wie im Abschnitt "Grundlegendes zum Formularauthentifizierungsworkflow" erläutert, leitet der FormsAuthenticationModule Benutzer automatisch zur Anmeldeseite um, wenn er versucht, auf eine Seite zuzugreifen, für die er nicht autorisiert ist. Es gibt auch ASP.NET Websteuerelemente, die anonymen Benutzern einen Link zur Anmeldeseite anzeigen. Dadurch wird die Frage gestellt: "Was ist die URL der Anmeldeseite?"

Standardmäßig erwartet das Formularauthentifizierungssystem, dass die Anmeldeseite Login.aspx benannt und im Stammverzeichnis der Webanwendung platziert wird. Wenn Sie eine andere Anmeldeseiten-URL verwenden möchten, können Sie dies tun, indem Sie sie in Web.config angeben. Wie Dies geschieht, erfahren Sie im folgenden Tutorial.

Die Anmeldeseite hat drei Aufgaben:

  1. Stellen Sie eine Schnittstelle bereit, die es dem Besucher ermöglicht, seine Anmeldeinformationen einzugeben.
  2. Ermitteln Sie, ob die übermittelten Anmeldeinformationen gültig sind.
  3. "Melden Sie sich an", indem Sie das Formularauthentifizierungsticket erstellen.

Erstellen der Benutzeroberfläche der Anmeldeseite

Beginnen wir mit der ersten Aufgabe. Fügen Sie dem Stammverzeichnis der Website mit dem Namen Login.aspx eine neue seite ASP.NET hinzu, und ordnen Sie sie der Website zu. master master Seite.

Hinzufügen einer neuen ASP.NET-Seite namens Login.aspx

Abbildung 8: Hinzufügen einer neuen ASP.NET Seite namens Login.aspx (Zum Anzeigen des Bilds in voller Größe klicken)

Die typische Benutzeroberfläche der Anmeldeseite besteht aus zwei Textfelder – eines für den Namen des Benutzers, eines für sein Kennwort – und einer Schaltfläche zum Übermitteln des Formulars. Websites enthalten häufig ein Kontrollkästchen "Erinnern Sie sich an mich", das das resultierende Authentifizierungsticket bei Browserneustarts beibehalten wird.

Fügen Sie Login.aspx zwei Textfelder hinzu, und legen Sie deren ID Eigenschaften auf Benutzername bzw. Kennwort fest. Legen Sie auch die Password-Eigenschaft TextMode auf Password fest. Fügen Sie als Nächstes ein CheckBox-Steuerelement hinzu, und legen Sie dessen ID Eigenschaft auf RememberMe und seine Text Eigenschaft auf "Remember Me" fest. Fügen Sie anschließend einen Button namens LoginButton hinzu, dessen Text Eigenschaft auf "Login" festgelegt ist. Fügen Sie schließlich ein Label-Websteuerelement hinzu, und legen Sie dessen ID Eigenschaft auf InvalidCredentialsMessage fest, dessen Text Eigenschaft auf "Ihr Benutzername oder Kennwort ist ungültig. Bitte versuchen Sie es noch einmal.", seine ForeColor Eigenschaft auf Red und seine Visible Eigenschaft auf False.

An diesem Punkt sollte Ihr Bildschirm wie der Screenshot in Abbildung 9 aussehen, und die deklarative Syntax Ihrer Seite sollte wie folgt aussehen:

<%@ 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>

Die Anmeldeseite enthält zwei Textfelder, ein CheckBox, eine Schaltfläche und eine Bezeichnung.

Abbildung 9: Die Anmeldeseite enthält zwei Textfelder, ein CheckBox-Element, eine Schaltfläche und eine Bezeichnung (klicken, um das bild in voller Größe anzuzeigen)

Erstellen Sie schließlich einen Ereignishandler für das Click-Ereignis von LoginButton. Doppelklicken Sie in der Designer einfach auf das Button-Steuerelement, um diesen Ereignishandler zu erstellen.

Ermitteln, ob die angegebenen Anmeldeinformationen gültig sind

Nun müssen wir Aufgabe 2 im Click-Ereignishandler der Schaltfläche implementieren, um zu ermitteln, ob die angegebenen Anmeldeinformationen gültig sind. Dazu muss ein Benutzerspeicher vorhanden sein, der alle Anmeldeinformationen der Benutzer enthält, damit wir ermitteln können, ob die angegebenen Anmeldeinformationen mit bekannten Anmeldeinformationen übereinstimmen.

Vor ASP.NET 2.0 waren Entwickler für die Implementierung ihrer eigenen Benutzerspeicher und das Schreiben des Codes verantwortlich, um die bereitgestellten Anmeldeinformationen für den Store zu überprüfen. Die meisten Entwickler würden den Benutzerspeicher in einer Datenbank implementieren und eine Tabelle mit dem Namen Benutzer mit Spalten wie Benutzername, Kennwort, Email, LastLoginDate usw. erstellen. Diese Tabelle würde also einen Datensatz pro Benutzerkonto enthalten. Die Überprüfung der vom Benutzer angegebenen Anmeldeinformationen umfasst das Abfragen der Datenbank nach einem übereinstimmenden Benutzernamen und dann die Sicherstellung, dass das Kennwort in der Datenbank dem angegebenen Kennwort entspricht.

Mit ASP.NET 2.0 sollten Entwickler einen der Mitgliedschaftsanbieter verwenden, um den Benutzerspeicher zu verwalten. In dieser Tutorialreihe verwenden wir den SqlMembershipProvider, der eine SQL Server Datenbank für den Benutzerspeicher verwendet. Bei Verwendung von SqlMembershipProvider müssen wir ein bestimmtes Datenbankschema implementieren, das die vom Anbieter erwarteten Tabellen, Ansichten und gespeicherten Prozeduren enthält. Wie Sie dieses Schema implementieren, erfahren Sie im Tutorial Erstellen des Mitgliedschaftsschemas in SQL Server. Wenn der Mitgliedschaftsanbieter eingerichtet ist, ist die Überprüfung der Anmeldeinformationen des Benutzers so einfach wie das Aufrufen der ValidateUser(username, password)-Methode der Membership-Klasse, die einen booleschen Wert zurückgibt, der angibt, ob die Gültigkeit der Kombination aus Benutzername und Kennwort. Da wir den Benutzerspeicher von SqlMembershipProvider noch nicht implementiert haben, können wir die ValidateUser-Methode der Membership-Klasse derzeit nicht verwenden.

Anstatt sich die Zeit zu nehmen, eine eigene benutzerdefinierte Benutzerdatenbanktabelle zu erstellen (die nach der Implementierung von SqlMembershipProvider veraltet wäre), müssen wir stattdessen die gültigen Anmeldeinformationen auf der Anmeldeseite selbst hartcodieren. Fügen Sie im Click-Ereignishandler von LoginButton den folgenden Code hinzu:

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;
}

Wie Sie sehen können, gibt es drei gültige Benutzerkonten – Scott, Jisun und Sam – und alle drei haben das gleiche Kennwort ("Kennwort"). Der Code durchläuft die Benutzer- und Kennwortarrays auf der Suche nach einer gültigen Übereinstimmung zwischen Benutzername und Kennwort. Wenn sowohl der Benutzername als auch das Kennwort gültig sind, müssen wir den Benutzer anmelden und dann zur entsprechenden Seite weiterleiten. Wenn die Anmeldeinformationen ungültig sind, wird die Bezeichnung InvalidCredentialsMessage angezeigt.

Wenn ein Benutzer gültige Anmeldeinformationen eingibt, habe ich erwähnt, dass er dann zur "entsprechenden Seite" weitergeleitet wird. Was ist jedoch die passende Seite? Denken Sie daran, dass ein Benutzer beim Aufrufen einer Seite, für die er nicht autorisiert ist, automatisch von FormsAuthenticationModule zur Anmeldeseite umgeleitet wird. Dabei wird die angeforderte URL über den ReturnUrl-Parameter in die Abfragezeichenfolge eingeschlossen. Das heißt, wenn ein Benutzer versucht hat, ProtectedPage.aspx zu besuchen, und er nicht dazu autorisiert war, würde die FormsAuthenticationModule sie zu folgendem Umleiten:

Login.aspx? ReturnUrl=ProtectedPage.aspx

Nach erfolgreicher Anmeldung sollte der Benutzer zurück zu ProtectedPage.aspx umgeleitet werden. Alternativ können Benutzer die Anmeldeseite auf eigene Faust besuchen. In diesem Fall sollten sie nach der Anmeldung des Benutzers an die Default.aspx Seite des Stammordners gesendet werden.

Anmelden des Benutzers

Vorausgesetzt, die angegebenen Anmeldeinformationen sind gültig, müssen wir ein Formularauthentifizierungsticket erstellen und den Benutzer bei der Website anmelden. Die FormsAuthentication-Klasse im System.Web.Security-Namespace bietet verschiedene Methoden zum Anmelden und Abmelden von Benutzern über das Formularauthentifizierungssystem. Obwohl es mehrere Methoden in der FormsAuthentication-Klasse gibt, sind die drei Methoden, die wir an dieser Stelle interessieren:

  • GetAuthCookie(username, persistCookie) – erstellt ein Formularauthentifizierungsticket für den angegebenen Benutzernamen. Als Nächstes erstellt und gibt diese Methode ein HttpCookie-Objekt zurück, das den Inhalt des Authentifizierungstickets enthält. Wenn persistCookie true ist, wird ein persistentes Cookie erstellt.
  • SetAuthCookie(username, persistCookie) – ruft die GetAuthCookie(username, persistCookie)-Methode auf, um das Formularauthentifizierungscookie zu generieren. Diese Methode fügt dann das von GetAuthCookie zurückgegebene Cookie der Cookies-Sammlung hinzu (vorausgesetzt, die cookiebasierte Formularauthentifizierung wird verwendet; andernfalls ruft diese Methode eine interne Klasse auf, die die cookielose Ticketlogik verarbeitet).
  • RedirectFromLoginPage(username, persistCookie) – Diese Methode ruft SetAuthCookie(username, persistCookie) auf und leitet den Benutzer dann zur entsprechenden Seite weiter.

GetAuthCookie ist praktisch, wenn Sie das Authentifizierungsticket ändern müssen, bevor Sie das Cookie in die Cookie-Sammlung schreiben. SetAuthCookie ist nützlich, wenn Sie das Formularauthentifizierungsticket erstellen und der Cookies-Sammlung hinzufügen möchten, den Benutzer jedoch nicht zur entsprechenden Seite umleiten möchten. Vielleicht möchten Sie sie auf der Anmeldeseite behalten oder an eine alternative Seite senden.

Da wir den Benutzer anmelden und zur entsprechenden Seite umleiten möchten, verwenden wir RedirectFromLoginPage. Aktualisieren Sie den Click-Ereignishandler von LoginButton, und ersetzen Sie die beiden kommentierten TODO-Zeilen durch die folgende Codezeile:

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

Beim Erstellen des Formularauthentifizierungstickets verwenden wir die Text-Eigenschaft von UserName TextBox für den Benutzernamensparameter für das Formularauthentifizierungsticket und den überprüften Zustand des RememberMe-CheckBox-Steuerelements für den persistCookie-Parameter .

Um die Anmeldeseite zu testen, besuchen Sie sie in einem Browser. Geben Sie zunächst ungültige Anmeldeinformationen ein, z. B. den Benutzernamen "Nope" und das Kennwort "wrong". Wenn Sie auf die Schaltfläche Anmeldung klicken, erfolgt ein Postback, und die Bezeichnung InvalidCredentialsMessage wird angezeigt.

Die Bezeichnung InvalidCredentialsMessage wird angezeigt, wenn ungültige Anmeldeinformationen eingegeben werden.

Abbildung 10: Die Bezeichnung InvalidCredentialsMessage wird angezeigt, wenn Ungültige Anmeldeinformationen eingegeben werden (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Geben Sie als Nächstes gültige Anmeldeinformationen ein, und klicken Sie auf die Schaltfläche Anmeldung. Dieses Mal, wenn das Postback erfolgt, wird ein Formularauthentifizierungsticket erstellt, und Sie werden automatisch zurück an Default.aspx weitergeleitet. Zu diesem Zeitpunkt haben Sie sich bei der Website angemeldet, obwohl es keine visuellen Hinweise gibt, die darauf hinweisen, dass Sie gerade angemeldet sind. In Schritt 4 erfahren Sie, wie Sie programmgesteuert ermitteln, ob ein Benutzer angemeldet ist oder nicht, und wie Sie den Benutzer identifizieren, der die Seite besucht.

Schritt 5 untersucht Techniken zum Abmelden eines Benutzers von der Website.

Schützen der Anmeldeseite

Wenn der Benutzer seine Anmeldeinformationen eingibt und das Formular für die Anmeldeseite übermittelt, werden die Anmeldeinformationen – einschließlich des Kennworts – im Nur-Text-Format über das Internet an den Webserver übertragen. Das bedeutet, dass jeder Hacker, der den Netzwerkdatenverkehr erschnüffelt, den Benutzernamen und das Kennwort sehen kann. Um dies zu verhindern, ist es wichtig, den Netzwerkdatenverkehr mithilfe von SSL (Secure Socket Layer) zu verschlüsseln. Dadurch wird sichergestellt, dass die Anmeldeinformationen (sowie das HTML-Markup der gesamten Seite) ab dem Zeitpunkt verschlüsselt werden, an dem sie den Browser verlassen, bis sie vom Webserver empfangen werden.

Sofern Ihre Website keine vertraulichen Informationen enthält, müssen Sie SSL nur auf der Anmeldeseite und auf anderen Seiten verwenden, auf denen das Kennwort des Benutzers andernfalls per Nur-Text über das Kabel gesendet würde. Sie müssen sich nicht um das Schützen des Formularauthentifizierungstickets kümmern, da es standardmäßig sowohl verschlüsselt als auch digital signiert ist (um Manipulationen zu verhindern). Eine ausführlichere Diskussion zur Sicherheit von Formularauthentifizierungstickets finden Sie im folgenden Tutorial.

Hinweis

Viele finanz- und medizinische Websites sind so konfiguriert, dass sie SSL auf allen Seiten verwenden, die für authentifizierte Benutzer zugänglich sind. Wenn Sie eine solche Website erstellen, können Sie das Formularauthentifizierungssystem so konfigurieren, dass das Formularauthentifizierungsticket nur über eine sichere Verbindung übertragen wird.

Schritt 4: Erkennen authentifizierter Besucher und Ermitteln ihrer Identität

An diesem Punkt haben wir die Formularauthentifizierung aktiviert und eine rudimentäre Anmeldeseite erstellt, aber wir müssen noch untersuchen, wie wir feststellen können, ob ein Benutzer authentifiziert oder anonym ist. In bestimmten Szenarien können wir verschiedene Daten oder Informationen anzeigen, je nachdem, ob ein authentifizierter oder anonymer Benutzer die Seite besucht. Darüber hinaus müssen wir häufig die Identität des authentifizierten Benutzers kennen.

Erweitern wir die vorhandene Default.aspx Seite, um diese Techniken zu veranschaulichen. Fügen Sie in Default.aspx zwei Panel-Steuerelemente hinzu, eines mit dem Namen AuthenticatedMessagePanel und eines mit dem Namen AnonymousMessagePanel. Fügen Sie im ersten Bereich ein Label-Steuerelement namens WelcomeBackMessage hinzu. Fügen Sie im zweiten Bereich ein HyperLink-Steuerelement hinzu, legen Sie die Text-Eigenschaft auf "Log In" und die NavigateUrl-Eigenschaft auf "~/Login.aspx" fest. An diesem Punkt sollte das deklarative Markup für Default.aspx wie folgt aussehen:

<%@ 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>

Wie Sie wahrscheinlich bereits erraten haben, besteht die Idee hier darin, nur das AuthenticatedMessagePanel für authentifizierte Besucher und nur das AnonymousMessagePanel für anonyme Besucher anzuzeigen. Um dies zu erreichen, müssen wir die Sichtbaren Eigenschaften dieser Panels festlegen, je nachdem, ob der Benutzer angemeldet ist oder nicht.

Die Request.IsAuthenticated-Eigenschaft gibt einen booleschen Wert zurück, der angibt, ob die Anforderung authentifiziert wurde. Geben Sie den folgenden Code in den Page_Load-Ereignishandlercode ein:

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;
    }
}

Wenn dieser Code vorhanden ist, besuchen Sie Default.aspx über einen Browser. Wenn Sie sich noch nicht angemeldet haben, wird ein Link zur Anmeldeseite angezeigt (siehe Abbildung 11). Klicken Sie auf diesen Link, und melden Sie sich bei der Website an. Wie wir in Schritt 3 gesehen haben, werden Sie nach der Eingabe Ihrer Anmeldeinformationen zu Default.aspx zurückgegeben, aber dieses Mal wird auf der Seite die Meldung "Willkommen zurück!" angezeigt (siehe Abbildung 12).

Beim anonymen Besuch wird ein Anmeldelink angezeigt.

Abbildung 11: Beim anonymen Besuch wird ein Anmeldelink angezeigt.

Authentifizierte Benutzer werden angezeigt.

Abbildung 12: Authentifizierte Benutzer werden mit "Willkommen zurück!" angezeigt. Nachricht

Wir können die identität des aktuell angemeldeten Benutzers über die User-Eigenschaft des HttpContext-Objekts ermitteln. Das HttpContext-Objekt stellt Informationen zur aktuellen Anforderung dar und ist die Basis für solche gängigen ASP.NET-Objekte wie "Response", "Request" und "Session". Die User-Eigenschaft stellt den Sicherheitskontext der aktuellen HTTP-Anforderung dar und implementiert die IPrincipal-Schnittstelle.

Die User-Eigenschaft wird von FormsAuthenticationModule festgelegt. Insbesondere wenn FormsAuthenticationModule ein Formularauthentifizierungsticket in der eingehenden Anforderung findet, erstellt es ein neues GenericPrincipal-Objekt und weist es der User-Eigenschaft zu.

Prinzipalobjekte (z. B. GenericPrincipal) bieten Informationen zur Identität des Benutzers und zu den Rollen, zu denen sie gehören. Die IPrincipal-Schnittstelle definiert zwei Member:

Wir können den Namen des aktuellen Besuchers mithilfe des folgenden Codes ermitteln:

string currentUsersName = User.Identity.Name;

Bei Verwendung der Formularauthentifizierung wird ein FormsIdentity-Objekt für die Identity-Eigenschaft von GenericPrincipal erstellt. Die FormsIdentity-Klasse gibt immer die Zeichenfolge "Forms" für ihre AuthenticationType-Eigenschaft und true für ihre IsAuthenticated-Eigenschaft zurück. Die Name-Eigenschaft gibt den Benutzernamen zurück, der beim Erstellen des Formularauthentifizierungstickets angegeben wurde. Zusätzlich zu diesen drei Eigenschaften umfasst FormsIdentity den Zugriff auf das zugrunde liegende Authentifizierungsticket über die Ticket-Eigenschaft. Die Ticket-Eigenschaft gibt ein Objekt vom Typ FormsAuthenticationTicket zurück, das Eigenschaften wie Expiration, IsPersistent, IssueDate, Name usw. aufweist.

Der wichtige Punkt, den Sie hier beachten sollten, ist, dass der in den Methoden FormsAuthentication.GetAuthCookie(username, persistCookie), FormsAuthentication.SetAuthCookie(username, persistCookie) und FormsAuthentication.RedirectFromLoginPage(username, persistCookie) angegebene Parameter der gleiche Wert ist, der von User.Identity.Name zurückgegeben wird. Darüber hinaus ist das mit diesen Methoden erstellte Authentifizierungsticket verfügbar, indem User.Identity in ein FormsIdentity-Objekt umstrukturiert und dann auf die Ticket-Eigenschaft zugegriffen wird:

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

Lassen Sie uns eine personalisierte Nachricht in Default.aspx bereitstellen. Aktualisieren Sie den Page_Load-Ereignishandler, sodass der Text-Eigenschaft der WelcomeBackMessage-Bezeichnung die Zeichenfolge "Willkommen zurück, Benutzername!" zugewiesen wird.

WelcomeBackMessage.Text = "Willkommen zurück, " + User.Identity.Name + "!";

Abbildung 13 zeigt die Auswirkungen dieser Änderung (bei der Anmeldung als Benutzer Scott).

Die Willkommensnachricht enthält den Namen des aktuell angemeldeten Benutzers.

Abbildung 13: Die Willkommensnachricht enthält den Namen des aktuell angemeldeten Benutzers.

Verwenden der Steuerelemente "LoginView" und "LoginName"

Die Anzeige verschiedener Inhalte für authentifizierte und anonyme Benutzer ist eine häufige Anforderung. so wird der Name des aktuell angemeldeten Benutzers angezeigt. Aus diesem Grund enthält ASP.NET zwei Websteuerelemente, die die in Abbildung 13 gezeigte Funktionalität bereitstellen, ohne dass eine einzige Codezeile geschrieben werden muss.

Das LoginView-Steuerelement ist ein vorlagenbasiertes Websteuerelement, das das Anzeigen verschiedener Daten für authentifizierte und anonyme Benutzer erleichtert. Die LoginView enthält zwei vordefinierte Vorlagen:

  • AnonymousTemplate: Jedes dieser Vorlage hinzugefügte Markup wird nur anonymen Besuchern angezeigt.
  • LoggedInTemplate: Das Markup dieser Vorlage wird nur authentifizierten Benutzern angezeigt.

Fügen wir das LoginView-Steuerelement der master Seite Site.master unserer Website hinzu. Anstatt jedoch nur das LoginView-Steuerelement hinzuzufügen, fügen wir sowohl ein neues ContentPlaceHolder-Steuerelement hinzu, als auch das LoginView-Steuerelement in diesem neuen ContentPlaceHolder-Steuerelement. Die Begründung für diese Entscheidung wird sich in Kürze erehen lassen.

Hinweis

Zusätzlich zu AnonymousTemplate und LoggedInTemplate kann das LoginView-Steuerelement rollenspezifische Vorlagen enthalten. Rollenspezifische Vorlagen zeigen Markup nur für die Benutzer an, die einer angegebenen Rolle angehören. Die rollenbasierten Features des LoginView-Steuerelements werden in einem zukünftigen Tutorial untersucht.

Fügen Sie zunächst einen ContentPlaceHolder namens LoginContent zur master Seite innerhalb des div-Navigationselements <> hinzu. Sie können einfach ein ContentPlaceHolder-Steuerelement aus der Toolbox in die Quellansicht ziehen und das resultierende Markup direkt über dem "TODO: Menu will go here..." platzieren. Text.

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

Fügen Sie als Nächstes ein LoginView-Steuerelement innerhalb von LoginContent ContentPlaceHolder hinzu. Inhalte, die in den ContentPlaceHolder-Steuerelementen der master Seite platziert werden, gelten als Standardinhalt für den ContentPlaceHolder. Das heißt, ASP.NET Seiten, die diese master Seite verwenden, können ihren eigenen Inhalt für jeden ContentPlaceHolder angeben oder den Standardinhalt der master Seite verwenden.

Die LoginView und andere Anmeldesteuerelemente befinden sich auf der Registerkarte Anmeldung der Toolbox.

Das LoginView-Steuerelement in der Toolbox

Abbildung 14: Das LoginView-Steuerelement in der Toolbox

Fügen Sie als Nächstes zwei <br/> -Elemente unmittelbar nach dem LoginView-Steuerelement hinzu, aber noch innerhalb des ContentPlaceHolder. An diesem Punkt sollte das Markup des div-Navigationselements <> wie folgt aussehen:

<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>

Die Vorlagen von LoginView können aus dem Designer oder dem deklarativen Markup definiert werden. Erweitern Sie im Designer von Visual Studio das Smarttag von LoginView, das die konfigurierten Vorlagen in einer Dropdownliste auflistet. Geben Sie den Text "Hello, stranger" in die AnonymousTemplate ein; Fügen Sie als Nächstes ein HyperLink-Steuerelement hinzu, und legen Sie die Eigenschaften Text und NavigateUrl auf "Log In" bzw. "~/Login.aspx" fest.

Wechseln Sie nach dem Konfigurieren der AnonymousTemplate zur LoggedInTemplate, und geben Sie den Text "Willkommen zurück" ein. Ziehen Sie dann ein LoginName-Steuerelement aus der Toolbox in die LoggedInTemplate, und platzieren Sie es unmittelbar nach dem Text "Willkommen zurück". Das LoginName-Steuerelement zeigt, wie der Name schon sagt, den Namen des aktuell angemeldeten Benutzers an. Intern gibt das LoginName-Steuerelement einfach die User.Identity.Name-Eigenschaft aus.

Nachdem Sie diese Ergänzungen zu den LoginView-Vorlagen gemacht haben, sollte das Markup in etwa wie folgt aussehen:

<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>

Mit dieser Ergänzung der Website. master master Seite wird auf jeder Seite unserer Website eine andere Meldung angezeigt, je nachdem, ob der Benutzer authentifiziert ist. Abbildung 15 zeigt die Default.aspx Seite, wenn sie vom Benutzer Jisun über einen Browser aufgerufen wird. Die Meldung "Willkommen zurück, Jisun" wird zweimal wiederholt: einmal im Navigationsbereich der master Seite auf der linken Seite (über das LoginView-Steuerelement, das wir gerade hinzugefügt haben) und einmal im Inhaltsbereich des Default.aspx (über Panel-Steuerelemente und programmgesteuerte Logik).

Das LoginView-Steuerelement wird angezeigt.

Abbildung 15: Das LoginView-Steuerelement zeigt "Willkommen zurück, Jisun" an.

Da die LoginView der Seite master hinzugefügt wurde, kann sie auf jeder Seite unserer Website angezeigt werden. Es kann jedoch Webseiten geben, auf denen wir diese Meldung nicht anzeigen möchten. Eine solche Seite ist die Anmeldeseite, da ein Link zur Anmeldeseite dort deplatziert erscheint. Da wir das LoginView-Steuerelement in einem ContentPlaceHolder auf der seite master platziert haben, können wir dieses Standardmarkup auf unserer Inhaltsseite überschreiben. Öffnen Sie Login.aspx, und wechseln Sie zum Designer. Da wir in Login.aspx für loginContent ContentPlaceHolder auf der seite master kein Content-Steuerelement explizit definiert haben, wird auf der Anmeldeseite das Standardmarkup der master Seite für diesen ContentPlaceHolder angezeigt. Sie können dies über die Designer sehen. Der LoginContent ContentPlaceHolder zeigt das Standardmarkup (das LoginView-Steuerelement) an.

Die Anmeldeseite zeigt den Standardinhalt für den LoginContent ContentPlaceHolder der Gestaltungsvorlage an.

Abbildung 16: Die Anmeldeseite zeigt den Standardinhalt für den LoginContent ContentPlaceHolder der Gestaltungsvorlage (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Um das Standardmarkup für LoginContent ContentPlaceHolder außer Kraft zu setzen, klicken Sie einfach mit der rechten Maustaste auf den Bereich im Designer, und wählen Sie im Kontextmenü die Option Benutzerdefinierten Inhalt erstellen aus. (Bei Verwendung von Visual Studio 2008 enthält contentPlaceHolder ein Smarttag, das bei Auswahl die gleiche Option bietet.) Dadurch wird dem Markup der Seite ein neues Inhaltssteuerelement hinzugefügt, das es uns ermöglicht, benutzerdefinierte Inhalte für diese Seite zu definieren. Sie können hier eine benutzerdefinierte Meldung hinzufügen, z. B. "Bitte melden Sie sich an...", lassen Sie diese aber einfach leer.

Hinweis

In Visual Studio 2005 wird beim Erstellen von benutzerdefinierten Inhalten ein leeres Inhaltssteuerelement auf der Seite ASP.NET erstellt. In Visual Studio 2008 kopiert das Erstellen von benutzerdefinierten Inhalten jedoch den Standardinhalt der master Seite in das neu erstellte Inhaltssteuerelement. Wenn Sie Visual Studio 2008 verwenden, stellen Sie nach dem Erstellen des neuen Inhaltssteuerelements sicher, dass Sie den Inhalt löschen, der von der Seite master kopiert wurde.

Abbildung 17 zeigt die Login.aspx Seite, wenn sie nach dieser Änderung von einem Browser aufgerufen wird. Beachten Sie, dass im linken Navigations-div <> keine Meldung "Hallo, Fremder" oder "Willkommen zurück, Benutzername" angezeigt wird, wie beim Besuch Default.aspx.

Auf der Anmeldeseite wird das Markup des Standardmäßigen LoginContent ContentPlaceHolder ausgeblendet.

Abbildung 17: Die Anmeldeseite blendet das Markup des Standardmäßigen LoginContent ContentPlaceHolder aus (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Schritt 5: Abmelden

In Schritt 3 haben wir uns das Erstellen einer Anmeldeseite zum Anmelden eines Benutzers bei der Website angesehen, aber wir müssen noch sehen, wie ein Benutzer abgemeldet werden kann. Neben Methoden zum Protokollieren eines Benutzers in stellt die FormsAuthentication-Klasse auch eine SignOut-Methode bereit. Die SignOut-Methode zerstört einfach das Formularauthentifizierungsticket, wodurch der Benutzer von der Website abgemeldet wird.

Das Anbieten eines Abmeldelinks ist ein so häufiges Feature, dass ASP.NET ein Steuerelement enthält, das speziell zum Abmelden eines Benutzers entwickelt wurde. Das LoginStatus-Steuerelement zeigt abhängig vom Authentifizierungs-status des Benutzers entweder ein LinkButton -Element "Login" oder "Logout" (Abmelden) an. Ein "Login"-LinkButton wird für anonyme Benutzer gerendert, während authentifizierten Benutzern ein LinkButton "Abmelden" angezeigt wird. Der Text für die LinkButtons "Login" und "Logout" kann über die LoginText- und LogoutText-Eigenschaften von LoginStatus konfiguriert werden.

Wenn Sie auf das LinkButton "Login" klicken, wird ein Postback ausgeführt, von dem aus eine Umleitung zur Anmeldeseite erfolgt. Wenn Sie auf das LinkButton-Element "Abmelden" klicken, ruft das LoginStatus-Steuerelement die FormsAuthentication.SignOff-Methode auf und leitet den Benutzer dann zu einer Seite um. Die Seite, zu der der angemeldete Benutzer umgeleitet wird, hängt von der LogoutAction-Eigenschaft ab, die einem der drei folgenden Werte zugewiesen werden kann:

  • Aktualisieren – die Standardeinstellung; Leitet den Benutzer auf die Seite um, die er gerade besucht hat. Wenn die Gerade besuchte Seite keine anonymen Benutzer zulässt, leitet FormsAuthenticationModule den Benutzer automatisch zur Anmeldeseite um.

Vielleicht sind Sie neugierig, warum hier eine Umleitung durchgeführt wird. Warum ist die explizite Umleitung erforderlich, wenn der Benutzer auf derselben Seite bleiben möchte? Der Grund ist, dass der Benutzer beim Klicken auf den LinkButton "Abmelden" weiterhin das Formularauthentifizierungsticket in seiner Cookies-Sammlung hat. Folglich ist die Postbackanforderung eine authentifizierte Anforderung. Das LoginStatus-Steuerelement ruft die SignOut-Methode auf, dies geschieht jedoch, nachdem formsAuthenticationModule den Benutzer authentifiziert hat. Daher bewirkt eine explizite Umleitung, dass der Browser die Seite erneut anzufordern. Wenn der Browser die Seite erneut anfordert, wurde das Formularauthentifizierungsticket entfernt, sodass die eingehende Anforderung anonym ist.

  • Umleitung: Der Benutzer wird zu der URL umgeleitet, die von der LogoutPageUrl-Eigenschaft von LoginStatus angegeben wird.
  • RedirectToLoginPage: Der Benutzer wird zur Anmeldeseite umgeleitet.

Fügen Sie der Seite master ein LoginStatus-Steuerelement hinzu, und konfigurieren Sie es so, dass die Option Umleitung verwendet wird, um den Benutzer an eine Seite zu senden, auf der eine Meldung angezeigt wird, die bestätigt, dass er abgemeldet wurde. Erstellen Sie zunächst eine Seite im Stammverzeichnis mit dem Namen Logout.aspx. Vergessen Sie nicht, diese Seite der Website zuzuordnen. master master Seite. Geben Sie als Nächstes eine Meldung im Markup der Seite ein, die dem Benutzer erklärt, dass er abgemeldet wurde.

Kehren Sie als Nächstes zur Website zurück. master master Seite, und fügen Sie ein LoginStatus-Steuerelement unterhalb der LoginView im LoginContent ContentPlaceHolder hinzu. Legen Sie die LogoutAction-Eigenschaft des LoginStatus-Steuerelements auf Redirect und die LogoutPageUrl-Eigenschaft auf "~/Logout.aspx" fest.

<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>

Da loginStatus sich außerhalb des LoginView-Steuerelements befindet, wird er sowohl für anonyme als auch für authentifizierte Benutzer angezeigt. Dies ist jedoch in Ordnung, da loginStatus das LinkButton "Login" oder "Logout" korrekt anzeigt. Mit dem Hinzufügen des LoginStatus-Steuerelements ist der HyperLink "Log In" in anonymousTemplate überflüssig, also entfernen Sie es.

Abbildung 18 zeigt Default.aspx, wenn Jisun zu Besuch kommt. Beachten Sie, dass in der linken Spalte die Meldung "Willkommen zurück, Jisun" zusammen mit einem Link zum Abmelden angezeigt wird. Wenn Sie auf linkButton abmelden klicken, wird ein Postback verursacht, Jisun aus dem System abgemeldet und dann an Logout.aspx umgeleitet. Wie Abbildung 19 zeigt, ist Jisun bei erreichen Logout.aspx sie bereits abgemeldet und daher anonym ist. Folglich wird in der linken Spalte der Text "Willkommen, Fremder" und ein Link zur Anmeldeseite angezeigt.

Default.aspx Shows

Abbildung 18: Default.aspx zeigt "Willkommen zurück, Jisun" zusammen mit einem LinkButton "Abmelden" (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Logout.aspx Shows

Abbildung 19: Logout.aspx zeigt "Willkommen, Fremder" zusammen mit einem LinkButton "Login" (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Hinweis

Ich ermutige Sie, die Seite Logout.aspx anzupassen, um den LoginContent ContentPlaceHolder der master-Seite auszublenden (wie bei Login.aspx in Schritt 4). Der Grund dafür ist, dass das vom LoginStatus-Steuerelement (das unter "Hello, stranger") gerenderte LinkButton "Login" den Benutzer an die Anmeldeseite sendet, indem er die aktuelle URL im Abfragezeichenfolgenparameter ReturnUrl übergibt. Kurz gesagt: Wenn ein Benutzer, der sich abgemeldet hat, auf das LinkButton "Login" von LoginStatus klickt und sich dann anmeldet, wird er zurück zu Logout.aspx weitergeleitet, was den Benutzer leicht verwirren kann.

Zusammenfassung

In diesem Tutorial haben wir mit einer Untersuchung des Formularauthentifizierungsworkflows begonnen und uns dann mit der Implementierung der Formularauthentifizierung in einer ASP.NET-Anwendung vertraut gemacht. Die Formularauthentifizierung wird von FormsAuthenticationModule unterstützt, das zwei Aufgaben hat: Identifizieren von Benutzern basierend auf ihrem Formularauthentifizierungsticket und Umleiten nicht autorisierter Benutzer zur Anmeldeseite.

Die FormsAuthentication-Klasse des .NET Framework enthält Methoden zum Erstellen, Überprüfen und Entfernen von Formularauthentifizierungstickets. Die Request.IsAuthenticated-Eigenschaft und das User-Objekt bieten zusätzliche programmgesteuerte Unterstützung zum Bestimmen, ob eine Anforderung authentifiziert ist, sowie Informationen zur Identität des Benutzers. Es gibt auch die Websteuerelemente LoginView, LoginStatus und LoginName, die Entwicklern eine schnelle, codefreie Möglichkeit bieten, viele allgemeine Anmeldeaufgaben auszuführen. Diese und andere Anmelde-bezogene Websteuerelemente werden in zukünftigen Tutorials ausführlicher untersucht.

In diesem Tutorial wurde eine cursorige Übersicht über die Formularauthentifizierung bereitgestellt. Wir haben nicht die verschiedenen Konfigurationsoptionen untersucht, die Funktionsweise von Formularauthentifizierungstickets ohne Cookies untersucht oder untersucht, wie ASP.NET den Inhalt des Formularauthentifizierungstickets schützt.

Viel Spaß beim Programmieren!

Weitere Informationen

Weitere Informationen zu den in diesem Tutorial behandelten Themen finden Sie in den folgenden Ressourcen:

Videoschulung zu Themen in diesem Tutorial

Zum Autor

Scott Mitchell, Autor von sieben ASP/ASP.NET-Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft-Webtechnologien. Scott arbeitet als unabhängiger Berater, Trainer und Autor. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.

Besonderer Dank an...

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Lead Reviewer für dieses Tutorial war Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Hauptprüfer für dieses Tutorial sind Alicja Maziarz, John Suru und Teresa Murphy. Möchten Sie meine bevorstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.