Share via


Benutzerbasierte Autorisierung (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 untersuchen wir das Einschränken des Zugriffs auf Seiten und das Einschränken der Funktionalität auf Seitenebene durch eine Vielzahl von Techniken.

Einführung

Die meisten Webanwendungen, die Benutzerkonten anbieten, tun dies teilweise, um bestimmten Besuchern den Zugriff auf bestimmte Seiten innerhalb der Website zu beschränken. Auf den meisten Online-Messageboard-Websites können beispielsweise alle Benutzer - anonym und authentifiziert - die Beiträge des Messageboards anzeigen, aber nur authentifizierte Benutzer können die Webseite besuchen, um einen neuen Beitrag zu erstellen. Und es kann Administrative Seiten geben, die nur für einen bestimmten Benutzer (oder eine bestimmte Gruppe von Benutzern) zugänglich sind. Darüber hinaus kann sich die Funktionalität auf Seitenebene von Benutzer zu Benutzer unterscheiden. Beim Anzeigen einer Liste von Beiträgen wird authentifizierten Benutzern eine Schnittstelle zum Bewerten jedes Beitrags angezeigt, während diese Schnittstelle für anonyme Besucher nicht verfügbar ist.

ASP.NET vereinfacht das Definieren benutzerbasierter Autorisierungsregeln. Mit nur ein wenig Markup in Web.configkönnen bestimmte Webseiten oder ganze Verzeichnisse gesperrt werden, sodass nur für eine bestimmte Teilmenge von Benutzern auf sie zugegriffen werden kann. Funktionen auf Seitenebene können basierend auf dem aktuell angemeldeten Benutzer über programmgesteuerte und deklarative Mittel aktiviert oder deaktiviert werden.

In diesem Tutorial untersuchen wir das Einschränken des Zugriffs auf Seiten und das Einschränken der Funktionalität auf Seitenebene durch eine Vielzahl von Techniken. Jetzt geht‘s los!

Ein Blick auf den URL-Autorisierungsworkflow

Wie im Tutorial Eine Übersicht über die Formularauthentifizierung erläutert, löst die Anforderung während des Lebenszyklus eine Reihe von Ereignissen aus, wenn die ASP.NET Runtime eine Anforderung für eine ASP.NET Ressource verarbeitet. 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.

Ein solches HTTP-Modul ist FormsAuthenticationModule. Wie in den vorherigen Tutorials erläutert, besteht die primäre Funktion von darin FormsAuthenticationModule , die Identität der aktuellen Anforderung zu bestimmen. Dies wird durch Überprüfen des Formularauthentifizierungstickets erreicht, das sich entweder in einem Cookie befindet oder in die URL eingebettet ist. Diese Identifizierung erfolgt während des EreignissesAuthenticateRequest.

Ein weiteres wichtiges HTTP-Modul ist das UrlAuthorizationModule, das als Reaktion auf das AuthorizeRequest Ereignis ausgelöst wird (das nach dem AuthenticateRequest Ereignis auftritt). Der UrlAuthorizationModule untersucht das Konfigurationsmarkup in Web.config , um zu ermitteln, ob die aktuelle Identität über die Berechtigung verfügt, die angegebene Seite zu besuchen. Dieser Prozess wird als URL-Autorisierung bezeichnet.

Wir untersuchen die Syntax für die URL-Autorisierungsregeln in Schritt 1, aber zunächst sehen wir uns an, was die UrlAuthorizationModule tut, je nachdem, ob die Anforderung autorisiert ist oder nicht. Wenn ermittelt UrlAuthorizationModule wird, dass die Anforderung autorisiert ist, tut sie nichts, und die Anforderung wird durch ihren Lebenszyklus fortgesetzt. Wenn die Anforderung jedoch nicht autorisiert ist, bricht die den UrlAuthorizationModule Lebenszyklus ab und weist das Response Objekt an, eine nicht autorisierte HTTP 401-status zurückzugeben. Wenn Sie die Formularauthentifizierung verwenden, wird diese HTTP 401-status nie an den Client zurückgegeben, da, wenn ein FormsAuthenticationModule HTTP 401 erkannt wird, status sie in eine HTTP 302-Umleitung zur Anmeldeseite ändert.

Abbildung 1 veranschaulicht den Workflow der ASP.NET-Pipeline, des FormsAuthenticationModuleund des UrlAuthorizationModule , wenn eine nicht autorisierte Anforderung eingeht. Abbildung 1 zeigt insbesondere eine Anforderung eines anonymen Besuchers für ProtectedPage.aspx, bei der es sich um eine Seite handelt, die anonymen Benutzern den Zugriff verweigert. Da der Besucher anonym ist, bricht der UrlAuthorizationModule die Anforderung ab und gibt eine HTTP 401 Unauthorized status zurück. Dann FormsAuthenticationModule konvertiert die 401-status in eine 302-Umleitungsseite zur Anmeldung. Nachdem der Benutzer über die Anmeldeseite authentifiziert wurde, wird er zu ProtectedPage.aspxweitergeleitet. Dieses Mal identifiziert der FormsAuthenticationModule den Benutzer basierend auf seinem Authentifizierungsticket. Nachdem der Besucher nun authentifiziert ist, ermöglicht der UrlAuthorizationModule den Zugriff auf die Seite.

Der Workflow für Formularauthentifizierung und URL-Autorisierung

Abbildung 1: Workflow für Formularauthentifizierung und URL-Autorisierung (Klicken Sie hier, um das vollständige Bild anzuzeigen)

Abbildung 1 zeigt die Interaktion, die auftritt, wenn ein anonymer Besucher versucht, auf eine Ressource zuzugreifen, die anonymen Benutzern nicht zur Verfügung steht. In einem solchen Fall wird der anonyme Besucher auf die Anmeldeseite mit der Seite weitergeleitet, die er in der Abfragezeichenfolge besuchen wollte. Nachdem sich der Benutzer erfolgreich angemeldet hat, wird er automatisch zurück zur Ressource weitergeleitet, die er ursprünglich anzeigen wollte.

Wenn die nicht autorisierte Anforderung von einem anonymen Benutzer gestellt wird, ist dieser Workflow einfach und für den Besucher leicht zu verstehen, was passiert ist und warum. Beachten Sie jedoch, dass alle FormsAuthenticationModule nicht autorisierten Benutzer zur Anmeldeseite weitergeleitet werden, auch wenn die Anforderung von einem authentifizierten Benutzer gestellt wird. Dies kann zu einer verwirrenden Benutzeroberfläche führen, wenn ein authentifizierter Benutzer versucht, eine Seite zu besuchen, für die er keine Autorität hat.

Stellen Sie sich vor, auf unserer Website wurden die URL-Autorisierungsregeln so konfiguriert, dass die ASP.NET Seite OnlyTito.aspx nur für Tito zugänglich ist. Stellen Sie sich nun vor, Sam besucht die Website, meldet sich an und versucht dann, zu besuchen OnlyTito.aspx. Der UrlAuthorizationModule hält den Anforderungslebenszyklus an und gibt eine HTTP 401 Nicht autorisierte status zurück, die erkannt FormsAuthenticationModule wird und sam dann zur Anmeldeseite umleitet. Da Sam sich jedoch bereits angemeldet hat, fragt sie sich möglicherweise, warum sie zurück auf die Anmeldeseite gesendet wurde. Sie könnte die Ursache dafür haben, dass ihre Anmeldeinformationen irgendwie verloren gegangen sind oder dass sie ungültige Anmeldeinformationen eingegeben hat. Wenn Sam ihre Anmeldeinformationen von der Anmeldeseite erneut eingibt, wird sie (erneut) angemeldet und zu OnlyTito.aspxweitergeleitet. Die UrlAuthorizationModule erkennt, dass Sam diese Seite nicht besuchen kann, und sie wird zur Anmeldeseite zurückgesendet.

Abbildung 2 zeigt diesen verwirrenden Workflow.

Der Standardworkflow kann zu einem verwirrenden Zyklus führen

Abbildung 2: Der Standardworkflow kann zu einem verwirrenden Zyklus führen (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Der in Abbildung 2 dargestellte Workflow kann auch den computeraffinesten Besucher schnell umspannen. Wir werden in Schritt 2 nach Möglichkeiten suchen, diesen verwirrenden Zyklus zu verhindern.

Hinweis

ASP.NET verwendet zwei Mechanismen, um zu bestimmen, ob der aktuelle Benutzer auf eine bestimmte Webseite zugreifen kann: URL-Autorisierung und Dateiautorisierung. Die Dateiautorisierung wird vom implementiert, der die FileAuthorizationModuleAutorität bestimmt, indem die angeforderten Datei-ACLs abgerufen werden. Die Dateiautorisierung wird am häufigsten mit Windows-Authentifizierung verwendet, da ACLs Berechtigungen sind, die für Windows-Konten gelten. Bei Verwendung der Formularauthentifizierung werden alle Anforderungen auf Betriebssystem- und Dateisystemebene vom gleichen Windows-Konto ausgeführt, unabhängig davon, ob der Benutzer die Website besucht. Da sich diese Tutorialreihe auf die Formularauthentifizierung konzentriert, wird die Dateiautorisierung nicht behandelt.

Der Bereich der URL-Autorisierung

Der UrlAuthorizationModule 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 ASP. NET wird UrlAuthorizationModule nur ausgeführt, wenn eine Anforderung von IIS an die ASP.NET Runtime delegiert wird. Standardmäßig verarbeitet IIS statische Inhalte selbst - wie HTML-Seiten und CSS-, JavaScript- und Bilddateien - und gibt Anforderungen nur dann an die ASP.NET Runtime weiter, wenn eine Seite mit der Erweiterung .aspx, .asmxoder .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 für alle Anforderungen aufgerufen UrlAuthorizationModule wird, was bedeutet, dass URL-Autorisierungsregeln für Dateien eines beliebigen Typs definiert werden können. Darüber hinaus enthält IIS 7 eine eigene URL-Autorisierungs-Engine. Weitere Informationen zur ASP.NET Integration und zur nativen URL-Autorisierungsfunktion von IIS 7 finden Sie unter Grundlegendes zur IIS7-URL-Autorisierung. Für einen ausführlicheren Blick auf ASP.NET- und IIS 7-Integration finden Sie eine Kopie von Shahram Khosravis Buch Professional IIS 7 and ASP.NET Integrated Programming (ISBN: 978-0470152539).

Kurz gesagt, in Versionen vor IIS 7 werden URL-Autorisierungsregeln nur auf Ressourcen angewendet, die von der ASP.NET Runtime verarbeitet werden. Mit IIS 7 ist es jedoch möglich, die native URL-Autorisierungsfunktion von IIS zu verwenden oder ASP. NET wird UrlAuthorizationModule in die HTTP-Pipeline von IIS integriert, wodurch diese Funktionalität auf alle Anforderungen erweitert wird.

Hinweis

Es gibt einige subtile, aber wichtige Unterschiede in der ASP. Die URL-Autorisierungsfunktion von UrlAuthorizationModule NET und IIS 7 verarbeitet die Autorisierungsregeln. In diesem Tutorial werden weder die URL-Autorisierungsfunktionalität von IIS 7 noch die Unterschiede in der Analyse von Autorisierungsregeln im Vergleich zu dem UrlAuthorizationModuleuntersucht. Weitere Informationen zu diesen Themen finden Sie in der IIS 7-Dokumentation auf MSDN oder unter www.iis.net.

Schritt 1: Definieren von URL-Autorisierungsregeln inWeb.config

Bestimmt UrlAuthorizationModule anhand der url-Autorisierungsregeln, die in der Konfiguration der Anwendung definiert sind, ob der Zugriff auf eine angeforderte Ressource für eine bestimmte Identität gewährt oder verweigert werden soll. Die Autorisierungsregeln werden im <authorization> -Element in Form von und <deny> untergeordneten <allow> Elementen geschrieben. Jedes untergeordnete Element und <deny> jedes <allow> untergeordnete Element kann Folgendes angeben:

  • Ein bestimmter Benutzer
  • Eine durch Trennzeichen getrennte Liste von Benutzern
  • Alle anonymen Benutzer, gekennzeichnet durch ein Fragezeichen (?)
  • Alle Benutzer, gekennzeichnet durch ein Sternchen (*)

Das folgende Markup veranschaulicht, wie die URL-Autorisierungsregeln verwendet werden, um Benutzern Tito und Scott zu erlauben und alle anderen zu verweigern:

<authorization>
 <allow users="Tito, Scott" />
 <deny users="*" />
</authorization>

Das <allow> -Element definiert, welche Benutzer zulässig sind – Tito und Scott –, während das <deny> Element anweist, dass alle Benutzer verweigert werden.

Hinweis

Die <allow> Elemente und <deny> können auch Autorisierungsregeln für Rollen angeben. In einem zukünftigen Tutorial werden wir die rollenbasierte Autorisierung untersuchen.

Die folgende Einstellung gewährt anderen Personen als Sam Zugriff (einschließlich anonymer Besucher):

<authorization>
 <deny users="Sam" />
</authorization>

Um nur authentifizierte Benutzer zuzulassen, verwenden Sie die folgende Konfiguration, die allen anonymen Benutzern den Zugriff verweigert:

<authorization>
 <deny users="?" />
</authorization>

Die Autorisierungsregeln werden innerhalb des <system.web> Elements in Web.config definiert und gelten für alle ASP.NET Ressourcen in der Webanwendung. Häufig verfügt eine Anwendung über unterschiedliche Autorisierungsregeln für verschiedene Abschnitte. Auf einer E-Commerce-Website können beispielsweise alle Besucher die Produkte durchsehen, Produktbewertungen anzeigen, den Katalog durchsuchen usw. Allerdings können nur authentifizierte Benutzer die Kasse oder die Seiten erreichen, um den Versandverlauf zu verwalten. Darüber hinaus kann es Teile der Website geben, auf die nur ausgewählte Benutzer zugreifen können, z. B. Websiteadministratoren.

ASP.NET vereinfacht das Definieren verschiedener Autorisierungsregeln für verschiedene Dateien und Ordner auf der Website. Die in der Datei des Web.config Stammordners angegebenen Autorisierungsregeln gelten für alle ASP.NET Ressourcen auf der Website. Diese Standardautorisierungseinstellungen können jedoch für einen bestimmten Ordner überschrieben werden, indem ein Web.config mit einem <authorization> Abschnitt hinzugefügt wird.

Wir aktualisieren unsere Website so, dass nur authentifizierte Benutzer die ASP.NET Seiten im Membership Ordner besuchen können. Um dies zu erreichen, müssen wir dem Ordner eine Web.config Datei hinzufügen und seine Membership Autorisierungseinstellungen so festlegen, dass anonyme Benutzer verweigert werden. Klicken Sie mit der rechten Maustaste auf den Membership Ordner im Projektmappen-Explorer, wählen Sie im Kontextmenü das Menü Neues Element hinzufügen aus, und fügen Sie eine neue Webkonfigurationsdatei mit dem Namen hinzuWeb.config.

Hinzufügen einer Web.config-Datei zum Mitgliedschaftsordner

Abbildung 3: Hinzufügen einer Web.config Datei zum Membership Ordner (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

An diesem Punkt sollte Ihr Projekt zwei Web.config Dateien enthalten: eine im Stammverzeichnis und eine im Membership Ordner.

Ihre Anwendung sollte jetzt zwei Web.config Dateien enthalten.

Abbildung 4: Ihre Anwendung sollte jetzt zwei Web.config Dateien enthalten (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Aktualisieren Sie die Konfigurationsdatei im Membership Ordner, sodass der Zugriff für anonyme Benutzer verhindert wird.

<?xml version="1.0"?>
<configuration>
 <system.web>
 <authorization>
 <deny users="?" />
 </authorization>
 </system.web>
</configuration>

Das war es schon!

Um diese Änderung zu testen, besuchen Sie die Startseite in einem Browser, und stellen Sie sicher, dass Sie abgemeldet sind. Da das Standardverhalten einer ASP.NET-Anwendung darin besteht, alle Besucher zuzulassen, und da wir keine Autorisierungsänderungen an der Datei des Stammverzeichnisses Web.config vorgenommen haben, können wir die Dateien im Stammverzeichnis als anonymer Besucher besuchen.

Klicken Sie auf den Link Benutzerkonten erstellen in der linken Spalte. Dadurch gelangen Sie zum ~/Membership/CreatingUserAccounts.aspx. Da die Web.config Datei im Membership Ordner Autorisierungsregeln definiert, um den anonymen Zugriff zu verhindern, bricht die UrlAuthorizationModule Anforderung ab und gibt eine http 401 Unauthorized status zurück. Die FormsAuthenticationModule ändert dies in einen 302-Umleitungs-status und sendet uns zur Anmeldeseite. Beachten Sie, dass die Seite, auf die wir () zugreifenCreatingUserAccounts.aspx möchten, über den querystring-Parameter an die ReturnUrl Anmeldeseite übergeben wird.

Da die URL-Autorisierungsregeln den anonymen Zugriff verbieten, werden wir zur Anmeldeseite umgeleitet.

Abbildung 5: Da die URL-Autorisierungsregeln den anonymen Zugriff verbieten, werden wir zur Anmeldeseite umgeleitet (Klicken Sie, um das vollständige Bild anzuzeigen)

Nach erfolgreicher Anmeldung werden wir zur CreatingUserAccounts.aspx Seite weitergeleitet. Dieses Mal ermöglicht die UrlAuthorizationModule den Zugriff auf die Seite, da wir nicht mehr anonym sind.

Anwenden von URL-Autorisierungsregeln auf einen bestimmten Standort

Die im <system.web> Abschnitt von definierten Autorisierungseinstellungen Web.config gelten für alle ASP.NET Ressourcen in diesem Verzeichnis und seinen Unterverzeichnissen (bis sie andernfalls von einer anderen Web.config Datei überschrieben werden). In einigen Fällen möchten wir jedoch möglicherweise, dass alle ASP.NET-Ressourcen in einem bestimmten Verzeichnis über eine bestimmte Autorisierungskonfiguration verfügen, mit Ausnahme von einer oder zwei bestimmten Seiten. Dies kann erreicht werden, indem ein <location> Element in Web.confighinzugefügt wird, das auf die Datei verweist, deren Autorisierungsregeln sich unterscheiden, und seine eindeutigen Autorisierungsregeln darin definieren.

Um die Verwendung des <location> -Elements zum Überschreiben der Konfigurationseinstellungen für eine bestimmte Ressource zu veranschaulichen, passen wir die Autorisierungseinstellungen so an, dass nur Tito besuchen CreatingUserAccounts.aspxkann. Fügen Sie dazu der Datei des Membership Ordners Web.config ein <location> Element hinzu, und aktualisieren Sie dessen Markup so, dass es wie folgt aussieht:

<?xml version="1.0"?>
<configuration>
 <system.web>
 <authorization>
 <deny users="?" />
 </authorization>
 </system.web>

 <location path="CreatingUserAccounts.aspx">
 <system.web>
 <authorization>
 <allow users="Tito" />
 <deny users="*" />
 </authorization>
 </system.web>
 </location>
</configuration>

Das <authorization> -Element in <system.web> definiert die Standard-URL-Autorisierungsregeln für ASP.NET Ressourcen im Ordner und seinen Membership Unterordnern. Das <location> -Element ermöglicht es uns, diese Regeln für eine bestimmte Ressource zu überschreiben. Im obigen Markup verweist das <location> -Element auf die CreatingUserAccounts.aspx Seite und gibt deren Autorisierungsregeln an, z. B. Tito zuzulassen, aber alle anderen zu verweigern.

Um diese Autorisierungsänderung zu testen, besuchen Sie zunächst die Website als anonymer Benutzer. Wenn Sie versuchen, eine Seite im Membership Ordner zu besuchen, z UserBasedAuthorization.aspx. B. , wird die UrlAuthorizationModule Anforderung abgelehnt, und Sie werden zur Anmeldeseite weitergeleitet. Nachdem Sie sich als beispielsweise Scott angemeldet haben, können Sie eine beliebige Seite im Ordner mit AusnahmeCreatingUserAccounts.aspxvon Membership besuchen. Wenn Sie versuchen, angemeldet zu sein CreatingUserAccounts.aspx , führt Tito jedoch zu einem nicht autorisierten Zugriffsversuch, der Sie zurück zur Anmeldeseite leitet.

Hinweis

Das <location> Element muss außerhalb des Konfigurationselements <system.web> angezeigt werden. Sie müssen ein separates <location> Element für jede Ressource verwenden, deren Autorisierungseinstellungen Sie überschreiben möchten.

Ein Blick auf die Verwendung der Autorisierungsregeln zum Gewähren oder Verweigern desUrlAuthorizationModuleZugriffs

Der UrlAuthorizationModule bestimmt, ob eine bestimmte Identität für eine bestimmte URL autorisiert werden soll, indem die URL-Autorisierungsregeln einzeln analysiert werden, beginnend mit der ersten und deren Abarbeitung. Sobald eine Übereinstimmung gefunden wird, wird dem Benutzer der Zugriff gewährt oder verweigert, je nachdem, ob die Übereinstimmung in einem <allow> - oder <deny> -Element gefunden wurde. Wenn keine Übereinstimmung gefunden wird, erhält der Benutzer Zugriff. Wenn Sie den Zugriff einschränken möchten, müssen Sie daher unbedingt ein <deny> Element als letztes Element in der URL-Autorisierungskonfiguration verwenden. Wenn Sie einen<deny> weglassen-Element, allen Benutzern wird Zugriff gewährt.

Um den Prozess zu verstehen, der von der zum Ermitteln der UrlAuthorizationModule Autorität verwendet wird, betrachten Sie die Beispiel-URL-Autorisierungsregeln, die wir zuvor in diesem Schritt untersucht haben. Die erste Regel ist ein <allow> Element, das den Zugriff auf Tito und Scott ermöglicht. Die zweite Regel ist ein <deny> Element, das jedem den Zugriff verweigert. Wenn ein anonymer Benutzer zu Besuch kommt, fragt er UrlAuthorizationModule zunächst: Ist entweder Scott oder Tito anonym? Die Antwort ist natürlich Nein, so dass es zur zweiten Regel übergeht. Ist anonym in der Gruppe aller? Da die Antwort hier Ja ist, wird die <deny> Regel in Kraft gesetzt und der Besucher wird zur Anmeldeseite weitergeleitet. Ähnlich, wenn Jisun zu Besuch, der mit der UrlAuthorizationModule Frage beginnt: Ist Jisun entweder Scott oder Tito? Da sie nicht ist, geht es UrlAuthorizationModule um die zweite Frage, Ist Jisun in der Gruppe von allen? Sie ist, so dass ihr auch der Zugriff verweigert wird. Schließlich, wenn Tito besucht, ist die erste Frage, die von der UrlAuthorizationModule gestellt wird, eine bejahende Antwort, so dass Tito Zugang gewährt wird.

Da die UrlAuthorizationModule Autorisierungsregeln von oben nach unten verarbeitet werden und bei jeder Übereinstimmung beendet werden, ist es wichtig, dass die spezifischeren Regeln vor den weniger spezifischen Regeln kommen. Das heißt, um Autorisierungsregeln zu definieren, die Jisun und anonyme Benutzer verbieten, aber alle anderen authentifizierten Benutzer zulassen, würden Sie mit der spezifischsten Regel beginnen - die sich auf Jisun auswirkt - und dann zu den weniger spezifischen Regeln übergehen : diejenigen, die alle anderen authentifizierten Benutzer zulassen, aber alle anonymen Benutzer ablehnen. Die folgenden URL-Autorisierungsregeln implementieren diese Richtlinie, indem zuerst Jisun verweigert und dann anonyme Benutzer verweigert werden. Allen authentifizierten Benutzern mit Ausnahme von Jisun wird Zugriff gewährt, da keine dieser <deny> Anweisungen übereinstimmt.

<authorization>
 <deny users="Jisun" />
 <deny users="?" />
</authorization>

Schritt 2: Beheben des Workflows für nicht autorisierte, authentifizierte Benutzer

Wie weiter oben in diesem Tutorial im Abschnitt A Look at the URL Authorization Workflow beschrieben, bricht die UrlAuthorizationModule Anforderung ab, sobald eine nicht autorisierte Anforderung angezeigt wird, und gibt eine http 401 Unauthorized status zurück. Diese 401 status wird von in FormsAuthenticationModule eine 302-Umleitungs-status geändert, die den Benutzer zur Anmeldeseite sendet. Dieser Workflow tritt bei jeder nicht autorisierten Anforderung auf, auch wenn der Benutzer authentifiziert ist.

Das Zurückgeben eines authentifizierten Benutzers auf die Anmeldeseite führt wahrscheinlich zu Verwirrung, da er sich bereits beim System angemeldet hat. Mit ein wenig Arbeit können wir diesen Workflow verbessern, indem wir authentifizierte Benutzer, die nicht autorisierte Anforderungen stellen, an eine Seite weiterleiten, die erklärt, dass sie versucht haben, auf eine eingeschränkte Seite zuzugreifen.

Erstellen Sie zunächst eine neue ASP.NET Seite im Stammordner der Webanwendung mit dem Namen UnauthorizedAccess.aspx. Vergessen Sie nicht, diese Seite der Site.master master-Seite zuzuordnen. Entfernen Sie nach dem Erstellen dieser Seite das Content-Steuerelement, das auf den LoginContent ContentPlaceHolder verweist, damit der Standardinhalt der master Seite angezeigt wird. Fügen Sie als Nächstes eine Meldung hinzu, die die Situation erläutert, nämlich, dass der Benutzer versucht hat, auf eine geschützte Ressource zuzugreifen. Nach dem Hinzufügen einer solchen Nachricht sollte das deklarative Markup der UnauthorizedAccess.aspx Seite wie folgt aussehen:

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeFile="UnauthorizedAccess.aspx.cs" Inherits="UnauthorizedAccess"
Title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
Runat="Server">
 <h2>Unauthorized Access</h2>
 <p>
 You have attempted to access a page that you are not authorized to view.
 </p>
 <p>
 If you have any questions, please contact the site administrator.
 </p>
</asp:Content>

Wir müssen nun den Workflow so ändern, dass, wenn eine nicht autorisierte Anforderung von einem authentifizierten Benutzer ausgeführt wird, dieser an die UnauthorizedAccess.aspx Seite anstelle der Anmeldeseite gesendet wird. Die Logik, die nicht autorisierte Anforderungen an die Anmeldeseite umleitet, wird in einer privaten Methode der FormsAuthenticationModule -Klasse vergraben, sodass wir dieses Verhalten nicht anpassen können. Was wir jedoch tun können, ist, der Anmeldeseite eine eigene Logik hinzuzufügen, die den Benutzer bei Bedarf zu UnauthorizedAccess.aspxumleitet.

Wenn der FormsAuthenticationModule einen nicht autorisierten Besucher zur Anmeldeseite umleitet, fügt er die angeforderte, nicht autorisierte URL mit dem Namen ReturnUrlan die Abfragezeichenfolge an. Wenn beispielsweise ein nicht autorisierter Benutzer versucht hat, zu besuchen OnlyTito.aspx, wird er FormsAuthenticationModule an Login.aspx?ReturnUrl=OnlyTito.aspxweitergeleitet. Wenn also die Anmeldeseite von einem authentifizierten Benutzer mit einer Abfragezeichenfolge erreicht wird, die den ReturnUrl Parameter enthält, wissen wir, dass dieser nicht authentifizierte Benutzer gerade versucht hat, eine Seite zu besuchen, für die er nicht autorisiert ist. In einem solchen Fall möchten wir sie zu UnauthorizedAccess.aspxumleiten.

Fügen Sie dazu dem Ereignishandler der Anmeldeseite Page_Load den folgenden Code hinzu:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        if (Request.IsAuthenticated && !string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))
        // This is an unauthorized, authenticated request...
        Response.Redirect("~/UnauthorizedAccess.aspx");
    }
}

Der obige Code leitet authentifizierte, nicht autorisierte Benutzer auf die UnauthorizedAccess.aspx Seite um. Um diese Logik in Aktion zu sehen, besuchen Sie die Website als anonymer Besucher, und klicken Sie in der linken Spalte auf den Link Benutzerkonten erstellen. Dadurch gelangen Sie zu der Seite, die ~/Membership/CreatingUserAccounts.aspx wir in Schritt 1 so konfiguriert haben, dass nur der Zugriff auf Tito zugelassen wird. Da anonyme Benutzer verboten sind, leitet uns die FormsAuthenticationModule zurück zur Anmeldeseite.

An diesem Punkt sind wir anonym, daher Request.IsAuthenticated werden false wir nicht zu UnauthorizedAccess.aspxumgeleitet. Stattdessen wird die Anmeldeseite angezeigt. Melden Sie sich als anderer Benutzer als Tito an, z. B. Bruce. Nach eingabe der entsprechenden Anmeldeinformationen leitet uns die Anmeldeseite zurück zu ~/Membership/CreatingUserAccounts.aspx. Da diese Seite jedoch nur für Tito zugänglich ist, sind wir nicht berechtigt, sie anzuzeigen und werden umgehend zur Anmeldeseite zurückgegeben. Dieses Mal wird jedoch Request.IsAuthenticated zurückgegeben true (und der ReturnUrl Querystring-Parameter ist vorhanden), sodass wir zur UnauthorizedAccess.aspx Seite weitergeleitet werden.

Authentifizierte, nicht autorisierte Benutzer werden zu UnauthorizedAccess.aspx umgeleitet.

Abbildung 6: Authentifizierte, nicht autorisierte Benutzer werden an umgeleitet (Klicken Sie hier, umUnauthorizedAccess.aspx das Bild in voller Größe anzuzeigen)

Dieser angepasste Workflow bietet eine sinnvollere und einfachere Benutzererfahrung, indem der in Abbildung 2 dargestellte Zyklus kurzgeschlossen wird.

Schritt 3: Einschränken der Funktionalität basierend auf dem aktuell angemeldeten Benutzer

Die URL-Autorisierung erleichtert die Angabe grober Autorisierungsregeln. Wie wir in Schritt 1 gesehen haben, können wir mit der URL-Autorisierung prägnant angeben, welche Identitäten zulässig sind und welche davon verweigert werden, eine bestimmte Seite oder alle Seiten in einem Ordner anzuzeigen. In bestimmten Szenarien möchten wir jedoch möglicherweise allen Benutzern erlauben, eine Seite zu besuchen, aber die Funktionalität der Seite basierend auf dem Benutzer einschränken, der sie besucht.

Betrachten Sie den Fall einer E-Commerce-Website, die es authentifizierten Besuchern ermöglicht, ihre Produkte zu überprüfen. Wenn ein anonymer Benutzer die Seite eines Produkts besucht, sieht er nur die Produktinformationen und erhält keine Möglichkeit, eine Bewertung zu hinterlassen. Ein authentifizierter Benutzer, der dieselbe Seite besucht, würde jedoch die Benutzeroberfläche zum Überprüfen sehen. Wenn der authentifizierte Benutzer dieses Produkt noch nicht überprüft hat, würde die Schnittstelle es ihm ermöglichen, eine Überprüfung zu übermitteln. Andernfalls wird ihnen ihre zuvor übermittelte Überprüfung angezeigt. Um dieses Szenario noch einen Schritt weiter zu gehen, enthält die Produktseite möglicherweise zusätzliche Informationen und bietet erweiterte Funktionen für die Benutzer, die für das E-Commerce-Unternehmen arbeiten. Beispielsweise kann die Produktseite den Lagerbestand auflisten und Optionen zum Bearbeiten des Preises und der Beschreibung des Produkts bei Besuch eines Mitarbeiters enthalten.

Solche differenzierten Autorisierungsregeln können entweder deklarativ oder programmgesteuert (oder durch eine Kombination aus beiden) implementiert werden. Im nächsten Abschnitt erfahren Sie, wie Sie eine differenzierte Autorisierung über das LoginView-Steuerelement implementieren. Danach werden wir programmgesteuerte Techniken untersuchen. Bevor wir uns jedoch mit der Anwendung feinkörniger Autorisierungsregeln befassen können, müssen wir zuerst eine Seite erstellen, deren Funktionalität vom Benutzer abhängt, der sie besucht.

Erstellen Sie eine Seite, auf der die Dateien in einem bestimmten Verzeichnis in einer GridView aufgelistet sind. Neben dem Namen, der Größe und anderen Informationen jeder Datei enthält gridView zwei LinkButton-Spalten: eine mit dem Titel Ansicht und eine mit dem Titel Löschen. Wenn sie auf Link anzeigen klicken, wird der Inhalt der ausgewählten Datei angezeigt. Wenn auf LinkButton löschen geklickt wird, wird die Datei gelöscht. Wir erstellen diese Seite zunächst so, dass die Ansichts- und Löschfunktionen für alle Benutzer verfügbar sind. In den Abschnitten Using the LoginView Control and Programmatically Limiting Functionality (Verwenden des LoginView-Steuerelements und Programmgesteuertes Einschränken der Funktionalität) erfahren Sie, wie Sie diese Features basierend auf dem Benutzer aktivieren oder deaktivieren, der die Seite besucht.

Hinweis

Die ASP.NET Seite, die wir erstellen möchten, verwendet ein GridView-Steuerelement, um eine Liste von Dateien anzuzeigen. Da sich diese Tutorialreihe auf Formularauthentifizierung, Autorisierung, Benutzerkonten und Rollen konzentriert, möchte ich nicht zu viel Zeit damit verbringen, die inneren Funktionsweisen des GridView-Steuerelements zu diskutieren. Dieses Tutorial enthält zwar spezifische schrittweise Anweisungen zum Einrichten dieser Seite, aber es befasst sich nicht mit den Details, warum bestimmte Entscheidungen getroffen wurden oder welche Auswirkungen bestimmte Eigenschaften auf die gerenderte Ausgabe haben. Eine gründliche Untersuchung des GridView-Steuerelements finden Sie in der Tutorialreihe Arbeiten mit Daten in ASP.NET 2.0 .

Öffnen Sie zunächst die UserBasedAuthorization.aspx Datei im Membership Ordner, und fügen Sie der Seite ein GridView-Steuerelement mit dem Namen FilesGridhinzu. Klicken Sie im Smarttag von GridView auf den Link Spalten bearbeiten, um das Dialogfeld Felder zu starten. Deaktivieren Sie hier das Kontrollkästchen Felder automatisch generieren in der unteren linken Ecke. Fügen Sie als Nächstes eine Schaltfläche Auswählen, eine Schaltfläche Löschen und zwei BoundFields aus der oberen linken Ecke hinzu (die Schaltflächen Auswählen und Löschen finden Sie unter dem Typ CommandField). Legen Sie die Eigenschaft der SelectText Schaltfläche Auswählen auf Ansicht und die Eigenschaften des ersten BoundFields HeaderText und DataField auf Name fest. Legen Sie die zweite BoundField-Eigenschaft HeaderText auf Size in Bytes, die - DataField Eigenschaft auf Length, die DataFormatString -Eigenschaft auf {0:N0} und die HtmlEncode -Eigenschaft auf False fest.

Klicken Sie nach dem Konfigurieren der GridView-Spalten auf OK, um das Dialogfeld Felder zu schließen. Legen Sie im Eigenschaftenfenster die Eigenschaft von DataKeyNames GridView auf festFullName. An diesem Punkt sollte das deklarative Markup von GridView wie folgt aussehen:

<asp:GridView ID="FilesGrid" DataKeyNames="FullName" runat="server" AutoGenerateColumns="False">
 <Columns>
 <asp:CommandField SelectText="View" ShowSelectButton="True"/>
 <asp:CommandField ShowDeleteButton="True" />
 <asp:BoundField DataField="Name" HeaderText="Name" />
 <asp:BoundField DataField="Length" DataFormatString="{0:N0}"
 HeaderText="Size in Bytes" HtmlEncode="False" />
 </Columns>
</asp:GridView>

Nachdem das Markup von GridView erstellt wurde, können wir den Code schreiben, mit dem die Dateien in einem bestimmten Verzeichnis abgerufen und an gridView gebunden werden. Fügen Sie dem Ereignishandler der Seite Page_Load den folgenden Code hinzu:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        string appPath = Request.PhysicalApplicationPath;
        DirectoryInfo dirInfo = new DirectoryInfo(appPath);

        FileInfo[] files = dirInfo.GetFiles();

        FilesGrid.DataSource = files;
        FilesGrid.DataBind();
    }
}

Der obige Code verwendet die DirectoryInfo -Klasse , um eine Liste der Dateien im Stammordner der Anwendung abzurufen. Die GetFiles() -Methode gibt alle Dateien im Verzeichnis als Array von FileInfo -Objekten zurück, das dann an gridView gebunden wird. Das FileInfo -Objekt verfügt über eine Reihe von Eigenschaften, z Name. B. , Lengthund IsReadOnly. Wie Sie anhand des deklarativen Markups sehen können, zeigt GridView nur die Name Eigenschaften und an Length .

Hinweis

Die DirectoryInfo Klassen und FileInfo befinden sich im System.IO Namespace. Daher müssen Sie entweder diesen Klassennamen ihre Namespacenamen voran stellen oder den Namespace in die Klassendatei importieren lassen (über using System.IO).

Nehmen Sie sich einen Moment Zeit, um diese Seite über einen Browser zu besuchen. Die Liste der Dateien, die sich im Stammverzeichnis der Anwendung befinden, wird angezeigt. Wenn Sie auf eine der LinkButtons anzeigen oder löschen klicken, wird ein Postback ausgelöst, es wird jedoch keine Aktion ausgeführt, da noch die erforderlichen Ereignishandler erstellt wurden.

GridView listet die Dateien im Stammverzeichnis der Webanwendung auf.

Abbildung 7: GridView listet die Dateien im Stammverzeichnis der Webanwendung auf (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Wir benötigen ein Mittel, um den Inhalt der ausgewählten Datei anzuzeigen. Kehren Sie zu Visual Studio zurück, und fügen Sie ein TextBox-Objekt mit dem Namen FileContents oberhalb von GridView hinzu. Legen Sie die TextMode -Eigenschaft auf MultiLine und die Columns Eigenschaften und Rows auf 95 % bzw. 10 fest.

<asp:TextBox ID="FileContents" runat="server" Rows="10"
TextMode="MultiLine" Width="95%"></asp:TextBox>

Erstellen Sie als Nächstes einen Ereignishandler für das GridView-EreignisSelectedIndexChanged, und fügen Sie den folgenden Code hinzu:

protected void FilesGrid_SelectedIndexChanged(object sender, EventArgs e)
{
    // Open the file and display it
    string fullFileName = FilesGrid.SelectedValue.ToString();
    string contents = File.ReadAllText(fullFileName);
    FileContents.Text = contents;
}

Dieser Code verwendet die GridView-Eigenschaft SelectedValue , um den vollständigen Dateinamen der ausgewählten Datei zu bestimmen. Intern wird auf die DataKeys Auflistung verwiesen, um die SelectedValueabzurufen, daher ist es zwingend erforderlich, dass Sie die Eigenschaft von DataKeyNames GridView auf Name festlegen, wie weiter oben in diesem Schritt beschrieben. Die File -Klasse wird verwendet, um den Inhalt der ausgewählten Datei in eine Zeichenfolge zu lesen, die dann der FileContents TextBox-Eigenschaft Text zugewiesen wird, wodurch der Inhalt der ausgewählten Datei auf der Seite angezeigt wird.

Der Inhalt der ausgewählten Datei wird im Textfeld angezeigt.

Abbildung 8: Der Inhalt der ausgewählten Datei wird im Textfeld angezeigt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Hinweis

Wenn Sie den Inhalt einer Datei anzeigen, die HTML-Markup enthält, und dann versuchen, eine Datei anzuzeigen oder zu löschen, erhalten Sie eine HttpRequestValidationException Fehlermeldung. Dies tritt auf, weil beim Postback der Inhalt des TextBox-Elements an den Webserver zurückgesendet wird. Standardmäßig löst ASP.NET einen Fehler aus HttpRequestValidationException , wenn potenziell gefährliche Postbackinhalte wie HTML-Markup erkannt werden. Um das Auftreten dieses Fehlers zu deaktivieren, deaktivieren Sie die Anforderungsüberprüfung für die Seite, indem Sie der @Page -Direktive hinzufügenValidateRequest="false". Weitere Informationen zu den Vorteilen der Anforderungsüberprüfung sowie zu den Vorsichtsmaßnahmen, die Sie beim Deaktivieren treffen sollten, finden Sie unter Anforderungsüberprüfung – Verhindern von Skriptangriffen.

Fügen Sie schließlich einen Ereignishandler mit dem folgenden Code für das GridView-EreignisRowDeleting hinzu:

protected void FilesGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    string fullFileName = FilesGrid.DataKeys[e.RowIndex].Value.ToString();
    FileContents.Text = string.Format("You have opted to delete {0}.", fullFileName);

    // To actually delete the file, uncomment the following line
    // File.Delete(fullFileName);
}

Der Code zeigt einfach den vollständigen Namen der zu löschenden Datei im FileContents Textfeld an, ohne die Datei tatsächlich zu löschen.

Wenn Sie auf die Schaltfläche Löschen klicken, wird die Datei nicht tatsächlich gelöscht.

Abbildung 9: Klicken auf die Schaltfläche "Löschen" Löscht die Datei nicht tatsächlich (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

In Schritt 1 haben wir die URL-Autorisierungsregeln so konfiguriert, dass anonyme Benutzer die Seiten im Membership Ordner nicht anzeigen können. Um eine feinkörnige Authentifizierung zu ermöglichen, können anonyme Benutzer die UserBasedAuthorization.aspx Seite besuchen, jedoch mit eingeschränkter Funktionalität. Um diese Seite so zu öffnen, dass alle Benutzer darauf zugreifen können, fügen Sie der Datei im Membership Ordner das Web.config folgende <location> Element hinzu:

<location path="UserBasedAuthorization.aspx">
 <system.web>
 <authorization>
 <allow users="*" />
 </authorization>
 </system.web>
</location>

Nachdem Sie dieses <location> Element hinzugefügt haben, testen Sie die neuen URL-Autorisierungsregeln, indem Sie sich von der Website abmelden. Als anonymer Nutzer sollten Sie die UserBasedAuthorization.aspx Seite besuchen dürfen.

Derzeit kann jeder authentifizierte oder anonyme Benutzer die UserBasedAuthorization.aspx Seite besuchen und Dateien anzeigen oder löschen. Lassen Sie uns dies so gestalten, dass nur authentifizierte Benutzer inhalte einer Datei anzeigen können und nur Tito eine Datei löschen kann. Solche differenzierten Autorisierungsregeln können deklarativ, programmgesteuert oder durch eine Kombination beider Methoden angewendet werden. Verwenden wir den deklarativen Ansatz, um zu begrenzen, wer den Inhalt einer Datei anzeigen kann. wir verwenden den programmgesteuerten Ansatz, um zu begrenzen, wer eine Datei löschen kann.

Verwenden des LoginView-Steuerelements

Wie wir in früheren Tutorials gesehen haben, ist das LoginView-Steuerelement nützlich, um verschiedene Schnittstellen für authentifizierte und anonyme Benutzer anzuzeigen, und bietet eine einfache Möglichkeit, Funktionen zu verbergen, auf die anonyme Benutzer nicht zugreifen können. Da anonyme Benutzer keine Dateien anzeigen oder löschen können, müssen wir das FileContents TextBox-Element nur anzeigen, wenn die Seite von einem authentifizierten Benutzer besucht wird. Um dies zu erreichen, fügen Sie der Seite ein LoginView-Steuerelement hinzu, nennen Sie es LoginViewForFileContentsTextBox, und verschieben Sie das FileContents deklarative Markup des TextBox-Steuerelements in das LoginView-Steuerelement LoggedInTemplate.

<asp:LoginView ID=" LoginViewForFileContentsTextBox " runat="server">
 <LoggedInTemplate>
 <p>
 <asp:TextBox ID="FileContents" runat="server" Rows="10"
 TextMode="MultiLine" Width="95%"></asp:TextBox>
 </p>
 </LoggedInTemplate>
</asp:LoginView>

Auf die Websteuerelemente in den LoginView-Vorlagen kann nicht mehr direkt über die CodeBehind-Klasse zugegriffen werden. Beispielsweise verweisen die FilesGrid Ereignishandler von SelectedIndexChanged GridView und RowDeleting derzeit auf das FileContents TextBox-Steuerelement mit Code wie:

FileContents.Text = text;

Dieser Code ist jedoch nicht mehr gültig. Durch Verschieben von FileContents TextBox in das LoggedInTemplate Textfeld kann nicht direkt auf das Textfeld zugegriffen werden. Stattdessen müssen wir die FindControl("controlId") -Methode verwenden, um programmgesteuert auf das Steuerelement zu verweisen. Aktualisieren Sie die FilesGrid Ereignishandler so, dass sie wie folgt auf das TextBox-Element verweisen:

TextBox FileContentsTextBox = LoginViewForFileContentsTextBox.FindControl("FileContents") as TextBox;
FileContentsTextBox.Text = text;

Nachdem Sie textBox in die LoginView verschoben LoggedInTemplate und den Code der Seite aktualisiert haben, um mithilfe des Musters auf das FindControl("controlId") TextBox-Element zu verweisen, besuchen Sie die Seite als anonymer Benutzer. Wie in Abbildung 10 dargestellt, wird textBox FileContents nicht angezeigt. LinkButton anzeigen wird jedoch weiterhin angezeigt.

Das LoginView-Steuerelement rendert das FileContents-Textfeld nur für authentifizierte Benutzer.

Abbildung 10: Das LoginView-Steuerelement rendert textBox FileContents nur für authentifizierte Benutzer (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Eine Möglichkeit zum Ausblenden der Schaltfläche Ansicht für anonyme Benutzer besteht darin, das GridView-Feld in ein TemplateField-Feld zu konvertieren. Dadurch wird eine Vorlage generiert, die das deklarative Markup für das View LinkButton-Element enthält. Wir können dann dem TemplateField ein LoginView-Steuerelement hinzufügen und linkButton innerhalb der LoginView LoggedInTemplateplatzieren, wodurch die Schaltfläche Ansicht vor anonymen Besuchern ausgeblendet wird. Klicken Sie dazu im Smarttag von GridView auf den Link Spalten bearbeiten, um das Dialogfeld Felder zu starten. Wählen Sie als Nächstes in der Liste in der unteren linken Ecke die Schaltfläche Auswählen aus, und klicken Sie dann auf den Link Dieses Feld in ein TemplateField konvertieren. Dadurch wird das deklarative Markup des Felds wie folgt geändert:

<asp:CommandField SelectText="View" ShowSelectButton="True"/>

Nach:

<asp:TemplateField ShowHeader="False">
 <ItemTemplate>
 <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
 CommandName="Select" Text="View"></asp:LinkButton>
 </ItemTemplate>
</asp:TemplateField>

An diesem Punkt können wir dem TemplateField eine LoginView hinzufügen. Das folgende Markup zeigt das View LinkButton nur für authentifizierte Benutzer an.

<asp:TemplateField ShowHeader="False">
 <ItemTemplate>
 <asp:LoginView ID="LoginView1" runat="server">
 <LoggedInTemplate>
 <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
 CommandName="Select" Text="View"></asp:LinkButton>
 </LoggedInTemplate>
 </asp:LoginView>
 </ItemTemplate>
</asp:TemplateField>

Wie Abbildung 11 zeigt, ist das Endergebnis nicht so hübsch, da die Ansichtsspalte weiterhin angezeigt wird, obwohl die LinkButtons in der Spalte ausgeblendet sind. Im nächsten Abschnitt wird erläutert, wie sie die gesamte GridView-Spalte (und nicht nur die LinkButton-Spalte) ausblenden.

Das LoginView-Steuerelement blendet die View LinkButtons für anonyme Besucher aus.

Abbildung 11: Das LoginView-Steuerelement blendet die View LinkButtons für anonyme Besucher aus (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Programmgesteuerte Einschränkung der Funktionalität

Unter bestimmten Umständen reichen deklarative Techniken nicht aus, um die Funktionalität auf eine Seite zu beschränken. Beispielsweise kann die Verfügbarkeit bestimmter Seitenfunktionen von Kriterien abhängen, die darüber hinausgehen, ob der Benutzer, der die Seite besucht, anonym oder authentifiziert ist. In solchen Fällen können die verschiedenen Benutzeroberflächenelemente programmgesteuert angezeigt oder ausgeblendet werden.

Um die Funktionalität programmgesteuert einzuschränken, müssen wir zwei Aufgaben ausführen:

  1. Bestimmen Sie, ob der Benutzer, der die Seite besucht, auf die Funktionalität zugreifen kann, und
  2. Ändern Sie die Benutzeroberfläche programmgesteuert, je nachdem, ob der Benutzer Zugriff auf die betreffende Funktionalität hat.

Um die Anwendung dieser beiden Aufgaben zu veranschaulichen, erlauben wir Tito nur, Dateien aus GridView zu löschen. Unsere erste Aufgabe ist es also, festzustellen, ob Tito die Seite besucht. Nachdem dies ermittelt wurde, müssen wir die Delete-Spalte von GridView ausblenden (oder anzeigen). Auf die Spalten von GridView kann über die Columns -Eigenschaft zugegriffen werden. Eine Spalte wird nur gerendert, wenn die Visible -Eigenschaft auf true (Standard) festgelegt ist.

Fügen Sie dem Ereignishandler den Page_Load folgenden Code hinzu, bevor Sie die Daten an GridView binden:

// Is this Tito visiting the page?
string userName = User.Identity.Name;
if (string.Compare(userName, "Tito", true) == 0)
    // This is Tito, SHOW the Delete column
    FilesGrid.Columns[1].Visible = true;
else
    // This is NOT Tito, HIDE the Delete column
    FilesGrid.Columns[1].Visible = false;

Wie im Tutorial Eine Übersicht über die Formularauthentifizierung erläutert, User.Identity.Name wird der Name der Identität zurückgegeben. Dies entspricht dem Benutzernamen, der im Anmeldesteuerelement eingegeben wurde. Wenn Tito die Seite besucht, wird die Eigenschaft der zweiten Spalte Visible von GridView auf truefestgelegt, andernfalls wird sie auf falsefestgelegt. Das Ergebnis ist, dass, wenn eine andere Person als Tito die Seite besucht, entweder ein anderer authentifizierter Benutzer oder ein anonymer Benutzer, die Spalte Löschen nicht gerendert wird (siehe Abbildung 12); Wenn Tito jedoch die Seite besucht, ist die Spalte Löschen vorhanden (siehe Abbildung 13).

Die Spalte

Abbildung 12: Die Spalte "Löschen" wird nicht gerendert, wenn sie von jemand anderem als Tito besucht wird (z. B. Bruce) (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Die Delete-Spalte wird für Tito gerendert.

Abbildung 13: Die Spalte "Löschen" wird für Tito gerendert (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Schritt 4: Anwenden von Autorisierungsregeln auf Klassen und Methoden

In Schritt 3 haben wir anonymen Benutzern das Anzeigen der Inhalte einer Datei untersagt und allen Benutzern außer Tito das Löschen von Dateien untersagt. Dies wurde erreicht, indem die zugehörigen Benutzeroberflächenelemente für nicht autorisierte Besucher durch deklarative und programmgesteuerte Techniken ausgeblendet wurden. Für unser einfaches Beispiel war das ordnungsgemäße Ausblenden der Benutzeroberflächenelemente einfach, aber was ist mit komplexeren Websites, bei denen es viele verschiedene Möglichkeiten gibt, dieselbe Funktionalität auszuführen? Was geschieht bei der Beschränkung dieser Funktionalität auf nicht autorisierte Benutzer, wenn wir vergessen, alle relevanten Benutzeroberflächenelemente auszublenden oder zu deaktivieren?

Eine einfache Möglichkeit, sicherzustellen, dass ein nicht autorisierter Benutzer nicht auf eine bestimmte Funktion zugreifen kann, besteht darin, diese Klasse oder Methode mit dem PrincipalPermission -Attribut zu versehen. Wenn die .NET-Runtime eine Klasse verwendet oder eine ihrer Methoden ausführt, wird überprüft, ob der aktuelle Sicherheitskontext über die Berechtigung zum Verwenden der Klasse oder Ausführen der Methode verfügt. Das PrincipalPermission -Attribut stellt einen Mechanismus bereit, mit dem wir diese Regeln definieren können.

Wir veranschaulichen die Verwendung des PrincipalPermission -Attributs für die GridView- SelectedIndexChanged und RowDeleting -Ereignishandler, um die Ausführung durch anonyme Benutzer bzw. andere Benutzer als Tito zu verhindern. Alles, was wir tun müssen, ist, das entsprechende Attribut auf jeder Funktionsdefinition hinzuzufügen:

[PrincipalPermission(SecurityAction.Demand, Authenticated=true)]
protected void FilesGrid_SelectedIndexChanged(object sender, EventArgs e)
{
    ...
}

[PrincipalPermission(SecurityAction.Demand, Name="Tito")]
protected void FilesGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    ...
}

Das -Attribut für den SelectedIndexChanged Ereignishandler schreibt vor, dass nur authentifizierte Benutzer den Ereignishandler ausführen können, wobei die Ausführung als Attribut für den RowDeleting Ereignishandler auf Tito beschränkt wird.

Wenn ein anderer Benutzer als Tito versucht, den RowDeleting Ereignishandler auszuführen, oder ein nicht authentifizierter Benutzer versucht, den SelectedIndexChanged Ereignishandler auszuführen, löst die .NET-Runtime einen aus SecurityException.

Wenn der Sicherheitskontext nicht autorisiert ist, die Methode auszuführen, wird eine SecurityException ausgelöst.

Abbildung 14: Wenn der Sicherheitskontext nicht autorisiert ist, die Methode auszuführen, wird ein SecurityException ausgelöst (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Hinweis

Um mehreren Sicherheitskontexten den Zugriff auf eine Klasse oder Methode zu ermöglichen, versehen Sie die Klasse oder Methode mit einem PrincipalPermission Attribut für jeden Sicherheitskontext. Das heißt, damit sowohl Tito als auch Bruce den RowDeleting Ereignishandler ausführen können, fügen Sie zweiPrincipalPermission Attribute hinzu:

[PrincipalPermission(SecurityAction.Demand, Name="Tito")]

[PrincipalPermission(SecurityAction.Demand, Name="Bruce")]

Neben ASP.NET Seiten verfügen viele Anwendungen auch über eine Architektur, die verschiedene Ebenen umfasst, z. B. Geschäftslogik und Datenzugriffsebenen. Diese Ebenen werden in der Regel als Klassenbibliotheken implementiert und bieten Klassen und Methoden für die Ausführung von geschäftslogik- und datenbezogenen Funktionen. Das PrincipalPermission -Attribut ist nützlich, um Autorisierungsregeln auf diese Ebenen anzuwenden.

Weitere Informationen zur Verwendung des Attributs zum Definieren von PrincipalPermission Autorisierungsregeln für Klassen und Methoden finden Sie im Blogeintrag Hinzufügen von Autorisierungsregeln zu Geschäfts- und Datenebenen von Scott Guthrie mit PrincipalPermissionAttributes.

Zusammenfassung

In diesem Tutorial haben wir uns mit der Anwendung von benutzerbasierten Autorisierungsregeln befasst. Wir begannen mit einem Blick auf ASP. URL-Autorisierungsframework von NET. Bei jeder Anforderung überprüft die ASP.NET-Engine UrlAuthorizationModule die in der Konfiguration der Anwendung definierten URL-Autorisierungsregeln, um festzustellen, ob die Identität für den Zugriff auf die angeforderte Ressource autorisiert ist. Kurz gesagt, die URL-Autorisierung erleichtert das Angeben von Autorisierungsregeln für eine bestimmte Seite oder für alle Seiten in einem bestimmten Verzeichnis.

Das URL-Autorisierungsframework wendet Autorisierungsregeln seitenweise an. Bei der URL-Autorisierung ist die anfordernde Identität für den Zugriff auf eine bestimmte Ressource autorisiert oder nicht. Viele Szenarien erfordern jedoch differenziertere Autorisierungsregeln. Anstatt zu definieren, wer auf eine Seite zugreifen darf, müssen wir möglicherweise jedem zugriff auf eine Seite erlauben, aber je nachdem, welcher Benutzer die Seite besucht, unterschiedliche Daten anzeigen oder unterschiedliche Funktionen anbieten. Bei der Autorisierung auf Seitenebene werden in der Regel bestimmte Benutzeroberflächenelemente ausgeblendet, um zu verhindern, dass nicht autorisierte Benutzer auf unzulässige Funktionen zugreifen. Darüber hinaus ist es möglich, Attribute zu verwenden, um den Zugriff auf Klassen und die Ausführung der zugehörigen Methoden für bestimmte Benutzer einzuschränken.

Viel Spaß beim Programmieren!

Weitere Informationen

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

Zum Autor

Scott Mitchell, Autor mehrerer ASP/ASP.NET-Bücher 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. Scott kann unter mitchell@4guysfromrolla.com oder über seinen Blog unter http://ScottOnWriting.NETerreicht werden.

Besonderer Dank an

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Möchten Sie meine bevorstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter ab mitchell@4GuysFromRolla.com.