Freigeben über


Rollenbasierte Autorisierung (VB)

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 Platform anstelle der Mitgliedschaftsanbieter verwenden, die zum Zeitpunkt der Veröffentlichung dieses Artikels vorgestellt wurden. ASP.NET Identity hat 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 für anspruchsbasierte Identitäten
  • Bessere Interoperabilität mit ASP.Net Core

Code herunterladen oder PDF herunterladen

Dieses Tutorial beginnt mit einem Blick darauf, wie das Rollenframework die Rollen eines Benutzers mit seinem Sicherheitskontext verknüpft. Anschließend wird untersucht, wie rollenbasierte URL-Autorisierungsregeln angewendet werden. Danach sehen wir uns die Verwendung deklarativer und programmgesteuerter Mittel zum Ändern der angezeigten Daten und der Funktionalität einer ASP.NET Seite an.

Einführung

Im Tutorial zur benutzerbasierten Autorisierung haben wir erfahren, wie Sie mithilfe der URL-Autorisierung angeben, welche Benutzer eine bestimmte Gruppe von Seiten besuchen können. Mit nur ein wenig Markup in Web.configkönnten wir ASP.NET anweisen, nur authentifizierten Benutzern den Besuch einer Seite zu gestatten. Oder wir könnten diktieren, dass nur Benutzer Tito und Bob zugelassen wurden, oder dass alle authentifizierten Benutzer mit Ausnahme von Sam zugelassen wurden.

Zusätzlich zur URL-Autorisierung haben wir uns auch mit deklarativen und programmgesteuerten Techniken zur Steuerung der angezeigten Daten und der Funktionalität einer Seite basierend auf dem Besuch des Benutzers befasst. Insbesondere haben wir eine Seite erstellt, auf der der Inhalt des aktuellen Verzeichnisses aufgeführt ist. Jeder konnte diese Seite besuchen, aber nur authentifizierte Benutzer konnten den Inhalt der Dateien anzeigen, und nur Tito konnte die Dateien löschen.

Das Anwenden von Autorisierungsregeln auf Benutzerbasis kann zu einem Buchführungs-Albtraum werden. Ein besser verwaltbarer Ansatz ist die Verwendung der rollenbasierten Autorisierung. Die gute Nachricht ist, dass die tools, die uns zur Anwendung von Autorisierungsregeln zur Verfügung stehen, mit Rollen genauso gut funktionieren wie für Benutzerkonten. URL-Autorisierungsregeln können Rollen anstelle von Benutzern angeben. Das LoginView-Steuerelement, das unterschiedliche Ausgaben für authentifizierte und anonyme Benutzer rendert, kann so konfiguriert werden, dass unterschiedliche Inhalte basierend auf den Rollen des angemeldeten Benutzers angezeigt werden. Und die Rollen-API enthält Methoden zum Bestimmen der Rollen des angemeldeten Benutzers.

Dieses Tutorial beginnt mit einem Blick darauf, wie das Rollenframework die Rollen eines Benutzers mit seinem Sicherheitskontext verknüpft. Anschließend wird untersucht, wie rollenbasierte URL-Autorisierungsregeln angewendet werden. Danach sehen wir uns die Verwendung deklarativer und programmgesteuerter Mittel zum Ändern der angezeigten Daten und der Funktionalität einer ASP.NET Seite an. Jetzt geht‘s los!

Grundlegendes zur Zuordnung von Rollen zum Sicherheitskontext eines Benutzers

Wenn eine Anforderung in die ASP.NET-Pipeline eintritt, wird sie einem Sicherheitskontext zugeordnet, der Informationen enthält, die den Anforderer identifizieren. Bei Verwendung der Formularauthentifizierung wird ein Authentifizierungsticket als Identitätstoken verwendet. Wie im Tutorial Eine Übersicht über die Formularauthentifizierung erläutert, ist die FormsAuthenticationModule für die Ermittlung der Identität des Anforderers verantwortlich, was während des EreignissesAuthenticateRequest der Fall ist.

Wenn ein gültiges, nicht abgelaufenes Authentifizierungsticket gefunden wird, decodiert es FormsAuthenticationModule , um die Identität des Anforderers zu ermitteln. Es erstellt ein neues GenericPrincipal -Objekt und weist dieses dem HttpContext.User -Objekt zu. Der Zweck eines Prinzipals wie GenericPrincipalbesteht darin, den Namen des authentifizierten Benutzers und die Rollen zu identifizieren, denen er angehört. Dieser Zweck wird dadurch deutlich, dass alle Prinzipalobjekte über eine Identity -Eigenschaft und eine IsInRole(roleName) -Methode verfügen. Der FormsAuthenticationModuleist jedoch nicht an der Aufzeichnung von Rolleninformationen interessiert, und das objekt, das GenericPrincipal erstellt wird, gibt keine Rollen an.

Wenn das Rollenframework aktiviert ist, tritt das RoleManagerModule HTTP-Modul nach und FormsAuthenticationModule identifiziert die Rollen des authentifizierten Benutzers während des PostAuthenticateRequest Ereignisses, das nach dem AuthenticateRequest Ereignis ausgelöst wird. Wenn die Anforderung von einem authentifizierten Benutzer stammt, überschreibt das RoleManagerModuleGenericPrincipal von erstellte FormsAuthenticationModule Objekt und ersetzt es durch ein RolePrincipal -Objekt. Die RolePrincipal -Klasse verwendet die Rollen-API, um zu bestimmen, zu welchen Rollen der Benutzer gehört.

Abbildung 1 zeigt den ASP.NET Pipelineworkflows bei Verwendung der Formularauthentifizierung und des Rollenframeworks. Führt FormsAuthenticationModule zuerst aus, identifiziert den Benutzer über sein Authentifizierungsticket und erstellt ein neues GenericPrincipal -Objekt. Als Nächstes überschreiben die RoleManagerModule Schritte in und das GenericPrincipal Objekt mit einem RolePrincipal -Objekt.

Wenn ein anonymer Benutzer die Website besucht, erstellt weder noch FormsAuthenticationModule ein RoleManagerModule Prinzipalobjekt.

Die ASP.NET Pipelineereignisse für einen authentifizierten Benutzer bei Verwendung der Formularauthentifizierung und des Rollenframeworks

Abbildung 1: Die ASP.NET Pipelineereignisse für einen authentifizierten Benutzer bei Verwendung der Formularauthentifizierung und des Rollenframeworks (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Die RolePrincipal -Methode des IsInRole(roleName) Objekts ruft auf Roles.GetRolesForUser , um die Rollen für den Benutzer abzurufen, um zu bestimmen, ob der Benutzer Mitglied von roleName ist. Bei Verwendung von führt dies SqlRoleProviderzu einer Abfrage an die Rollenspeicherdatenbank. Bei Verwendung von rollenbasierten URL-Autorisierungsregeln wird die -IsInRoleMethode von RolePrincipalbei jeder Anforderung an eine Seite aufgerufen, die durch die rollenbasierten URL-Autorisierungsregeln geschützt ist. Anstatt bei jeder Anforderung die Rolleninformationen in der Datenbank nachschlagen zu müssen, enthält das Roles Framework eine Option zum Zwischenspeichern der Benutzerrollen in einem Cookie.

Wenn das Rollenframework so konfiguriert ist, dass die Rollen des Benutzers in einem Cookie zwischengespeichert werden, wird das RoleManagerModule Cookie während des EreignissesEndRequest der ASP.NET Pipeline erstellt. Dieses Cookie wird in nachfolgenden Anforderungen in verwendet, wenn PostAuthenticateRequestdas RolePrincipal -Objekt erstellt wird. Wenn das Cookie gültig ist und nicht abgelaufen ist, werden die Daten im Cookie analysiert und verwendet, um die Rollen des Benutzers aufzufüllen. Dadurch wird verhindert, dass die RolePrincipal -Klasse aufgerufen werden muss, Roles um die Rollen des Benutzers zu bestimmen. Abbildung 2 zeigt diesen Workflow.

Die Rolleninformationen des Benutzers können in einem Cookie gespeichert werden, um die Leistung zu verbessern.

Abbildung 2: Die Rolleninformationen des Benutzers können in einem Cookie gespeichert werden, um die Leistung zu verbessern (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Der Cookiemechanismus für den Rollencache ist standardmäßig deaktiviert. Sie kann über das <roleManager>-Konfigurationsmarkup in Web.configaktiviert werden. Im Tutorial Erstellen und Verwalten von Rollen wurde die Verwendung des <roleManager> -Elements zum Angeben von Rollenanbietern erläutert. Daher sollten Sie dieses Element bereits in der Datei Ihrer Anwendung Web.config enthalten. Die Cookieeinstellungen für den Rollencache werden als Attribute des <roleManager>-Elements angegeben und in Tabelle 1 zusammengefasst.

Hinweis

Die in Tabelle 1 aufgeführten Konfigurationseinstellungen geben die Eigenschaften des resultierenden Rollencachecookies an. Weitere Informationen zu Cookies, ihrer Funktionsweise und ihren verschiedenen Eigenschaften finden Sie in diesem Tutorial zu Cookies.

Eigenschaft Beschreibung
cacheRolesInCookie Ein boolescher Wert, der angibt, ob die Cookiezwischenspeicherung verwendet wird. Der Standardwert lautet false.
cookieName Der Name des Rollencachecookies. Der Standardwert ist ". ASPXROLES".
cookiePath Der Pfad für das Rollennamen-Cookie. Mit dem Path-Attribut kann ein Entwickler den Bereich eines Cookies auf eine bestimmte Verzeichnishierarchie beschränken. Der Standardwert ist "/", der den Browser informiert, das Authentifizierungsticket-Cookie an jede Anforderung an die Domäne zu senden.
cookieProtection Gibt an, welche Techniken zum Schutz des Rollencachecookies verwendet werden. Zulässige Werte sind: All (Standard); Encryption; Noneund Validation.md)

| cookieRequireSSL | Ein boolescher Wert, der angibt, ob eine SSL-Verbindung erforderlich ist, um das Authentifizierungscookies zu übertragen. Der Standardwert ist false cookieSlidingExpiration false createPersistentCookieis set totrue. | | cookieTimeout | Specifies the time, in minutes, after which the authentication ticket cookie expires. The default value is30. This value is only pertinent when createPersistentCookieis set totrue. | | createPersistentCookie | A Boolean value that specifies whether the role cache cookie is a session cookie or persistent cookie. Iffalse, a persistent cookie is used; it expires (the default), a session cookie is used, which is deleted when the browser is closed. IfcookieTimeoutnumber of minutes after it has been created or after the previous visit, depending on the value ofcookieSlidingExpiration. | | domain| Specifies the cookie's domain value. The default value is an empty string, which causes the browser to use the domain from which it was issued (such as www.yourdomain.com). In this case, the cookie will <strong>not</strong> be sent when making requests to subdomains, such as admin.yourdomain.com. If you want the cookie to be passed to all subdomains you need to customize thedomainattribute, setting it to "yourdomain.com". | | maxCachedResults | Specifies the maximum number of role names that are cached in the cookie. The default is 25. TheRoleManagerModule maxCachedResults RoleManagerModuledoes not create a cookie for users that belong to more thanmaxCachedResultsroles. Consequently, theRolePrincipalobject'sIsInRolemethod will use theRolesclass to determine the user's roles. The reasonmaxCachedResultsexists is because many user agents do not permit cookies larger than 4,096 bytes. So this cap is meant to reduce the likelihood of exceeding this size limitation. If you have extremely long role names, you may want to consider specifying a smaller. This value is only pertinent when | A Boolean value that indicates whether the cookie's timeout is reset each time the user visits the site during a single session. The default value is. | | maxCachedResults-Wert; Wenn Sie extrem kurze Rollennamen haben, können Sie diesen Wert wahrscheinlich erhöhen. |

Tabelle 1: Konfigurationsoptionen für Rollencachecookies

Konfigurieren wir unsere Anwendung so, dass nicht persistente Rollencachecookies verwendet werden. Aktualisieren Sie dazu das <roleManager> Element in Web.config , um die folgenden cookiebezogenen Attribute einzuschließen:

<roleManager enabled="true" 
          defaultProvider="SecurityTutorialsSqlRoleProvider"
          cacheRolesInCookie="true"
          createPersistentCookie="false"
          cookieProtection="All">

     <providers>
     ...
     </providers>
</roleManager>

Ich habe das <roleManager>Element ; aktualisiert, indem ich drei Attribute hinzugefügt habe: cacheRolesInCookie, createPersistentCookieund cookieProtection. Wenn Sie auf truefestlegencacheRolesInCookie, RoleManagerModule werden die Rollen des Benutzers jetzt automatisch in einem Cookie zwischengespeichert, anstatt die Rolleninformationen des Benutzers bei jeder Anforderung suchen zu müssen. Ich setz die createPersistentCookie Attribute und cookieProtection explizit auf false bzw All. . Technisch gesehen musste ich keine Werte für diese Attribute angeben, da ich sie nur ihren Standardwerten zugewiesen habe, aber ich habe sie hier eingefügt, um deutlich zu machen, dass ich keine permanenten Cookies verwende und dass das Cookie sowohl verschlüsselt als auch überprüft ist.

Das war es schon! Fortan speichert das Rollenframework die Rollen der Benutzer in Cookies zwischen. Wenn der Browser des Benutzers keine Cookies unterstützt oder seine Cookies gelöscht oder verloren gehen, ist dies irgendwie keine große Sache – das RolePrincipal Objekt verwendet einfach die Roles -Klasse, falls kein Cookie (oder ein ungültiges oder abgelaufenes) verfügbar ist.

Hinweis

Die Microsoft-Gruppe Patterns & Practices rät von der Verwendung persistenter Rollencache-Cookies ab. Da der Besitz des Rollencachecookies ausreicht, um die Rollenmitgliedschaft nachzuweisen, kann ein Hacker, wenn er irgendwie Zugriff auf das Cookie eines gültigen Benutzers erhalten kann, die Identität dieses Benutzers annehmen. Die Wahrscheinlichkeit, dass dies geschieht, steigt, wenn das Cookie im Browser des Benutzers gespeichert wird. Weitere Informationen zu dieser Sicherheitsempfehlung sowie zu weiteren Sicherheitsbedenken finden Sie in der Sicherheitsfrageliste für ASP.NET 2.0.

Schritt 1: Definieren Role-Based URL-Autorisierungsregeln

Wie im Tutorial "Benutzerbasierte Autorisierung" erläutert, bietet die URL-Autorisierung eine Möglichkeit, den Zugriff auf eine Reihe von Seiten auf Benutzer- oder Rollenbasis zu beschränken. Die URL-Autorisierungsregeln werden in Web.config der Verwendung des <authorization> Elements mit <allow> und <deny> untergeordneten Elementen beschrieben. Zusätzlich zu den benutzerbezogenen Autorisierungsregeln, die in früheren Tutorials erläutert wurden, kann jedes <allow> untergeordnete <deny> Element auch Folgendes enthalten:

  • Eine bestimmte Rolle
  • Eine durch Trennzeichen getrennte Liste von Rollen

Beispielsweise gewähren die URL-Autorisierungsregeln diesen Benutzern in den Rollen Administratoren und Vorgesetzte Zugriff, verweigern jedoch allen anderen den Zugriff:

<authorization>

     <allow roles="Administrators, Supervisors" />
     <deny users="*" />
</authorization>

Das <allow> Element im obigen Markup gibt an, dass die Rollen "Administratoren" und "Supervisors" zulässig sind. Das <deny>-Element weist an, dass alle Benutzer verweigert werden.

Konfigurieren Wir unsere Anwendung so, dass die ManageRoles.aspxSeiten , UsersAndRoles.aspxund CreateUserWizardWithRoles.aspx nur für diese Benutzer in der Rolle Administratoren zugänglich sind, während die RoleBasedAuthorization.aspx Seite für alle Besucher zugänglich bleibt.

Um dies zu erreichen, fügen Sie dem Roles Ordner eine Datei hinzuWeb.config.

Hinzufügen einer Web.config datei zum Verzeichnis

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

Fügen Sie als Nächstes das folgende Konfigurationsmarkup hinzu Web.config:

<?xml version="1.0"?>

<configuration>
     <system.web>
          <authorization>
               <allow roles="Administrators" />
               <deny users="*"/>
          </authorization>

     </system.web>

     <!-- Allow all users to visit RoleBasedAuthorization.aspx -->
     <location path="RoleBasedAuthorization.aspx">
          <system.web>
               <authorization>
                    <allow users="*" />

               </authorization>
          </system.web>
     </location>
</configuration>

Das <authorization> Element im <system.web> Abschnitt gibt an, dass nur Benutzer in der Rolle Administratoren auf die ASP.NET Ressourcen im Roles Verzeichnis zugreifen können. Das <location> -Element definiert einen alternativen Satz von URL-Autorisierungsregeln für die RoleBasedAuthorization.aspx Seite, sodass alle Benutzer die Seite besuchen können.

Melden Sie sich nach dem Speichern Ihrer Änderungen in Web.configals Benutzer an, der nicht in der Rolle Administratoren ist, und versuchen Sie dann, eine der geschützten Seiten zu besuchen. Die UrlAuthorizationModule erkennt, dass Sie nicht berechtigt sind, die angeforderte Ressource zu besuchen. FormsAuthenticationModule Daher werden Sie zur Anmeldeseite weitergeleitet. Die Anmeldeseite leitet Sie dann zur UnauthorizedAccess.aspx Seite weiter (siehe Abbildung 4). Diese letzte Umleitung von der Anmeldeseite zu UnauthorizedAccess.aspx erfolgt aufgrund von Code, den wir der Anmeldeseite in Schritt 2 des Tutorials zur benutzerbasierten Autorisierung hinzugefügt haben. Insbesondere leitet die Anmeldeseite jeden authentifizierten Benutzer automatisch an, UnauthorizedAccess.aspx wenn die Abfragezeichenfolge einen ReturnUrl Parameter enthält, da dieser Parameter angibt, dass der Benutzer auf der Anmeldeseite angekommen ist, nachdem er versucht hat, eine Seite anzuzeigen, für die er nicht autorisiert war.

Nur Benutzer in der Rolle

Abbildung 4: Nur Benutzer in der Rolle "Administratoren" können die geschützten Seiten anzeigen (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Melden Sie sich ab, und melden Sie sich dann als Benutzer an, der sich in der Rolle Administratoren befindet. Nun sollten Sie die drei geschützten Seiten anzeigen können.

Tito kann die Seite

Abbildung 5: Tito kann die UsersAndRoles.aspx Seite besuchen, da er sich in der Administratorrolle befindet (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Hinweis

Bei der Angabe von URL-Autorisierungsregeln – für Rollen oder Benutzer – ist es wichtig zu beachten, dass die Regeln einzeln und von oben nach unten analysiert werden. 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 auf ein oder mehrere Benutzerkonten einschränken möchten, ist es daher unerlässlich, dass Sie ein <deny> Element als letztes Element in der URL-Autorisierungskonfiguration verwenden. Wenn Ihre URL-Autorisierungsregeln keine<deny>-Element, allen Benutzern wird Zugriff gewährt. Eine ausführlichere Diskussion darüber, wie die URL-Autorisierungsregeln analysiert werden, finden Sie im Abschnitt "A Look on how the Uses the UrlAuthorizationModule Authorization Rules to Grant or Deny Access" im Tutorial Zur benutzerbasierten Autorisierung.

Schritt 2: Einschränken der Funktionalität basierend auf den Aktuell angemeldeten Benutzerrollen

Die URL-Autorisierung macht es einfach, grobe Autorisierungsregeln anzugeben, die angeben, welche Identitäten zulässig sind und welchen Identitäten das Anzeigen einer bestimmten Seite (oder aller Seiten in einem Ordner und seinen Unterordnern) verweigert wird. In bestimmten Fällen möchten wir jedoch allen Benutzern den Besuch einer Seite erlauben, aber die Funktionalität der Seite basierend auf den Rollen des besuchenden Benutzers einschränken. Dies kann das Anzeigen oder Ausblenden von Daten basierend auf der Rolle des Benutzers oder das Anbieten zusätzlicher Funktionen für Benutzer, die zu einer bestimmten Rolle gehören, umfassen.

Solche feinkörnigen rollenbasierten Autorisierungsregeln können entweder deklarativ oder programmgesteuert (oder durch eine Kombination der beiden) implementiert werden. Im nächsten Abschnitt erfahren Sie, wie Sie die deklarative Feinkornautorisierung über das LoginView-Steuerelement implementieren. Anschließend werden wir programmgesteuerte Techniken untersuchen. Bevor wir uns jedoch mit der Anwendung feiner Autorisierungsregeln befassen können, müssen wir zuerst eine Seite erstellen, deren Funktionalität von der Rolle des Benutzers abhängt, der sie besucht.

Erstellen Sie eine Seite, auf der alle Benutzerkonten im System in einer GridView aufgelistet sind. Die GridView enthält den Benutzernamen, die E-Mail-Adresse, das Datum der letzten Anmeldung und kommentare zum Benutzer. Zusätzlich zur Anzeige der Benutzerinformationen enthält die GridView die Bearbeitungs- und Löschfunktionen. Zunächst erstellen wir diese Seite mit der Bearbeitungs- und Löschfunktion, die allen Benutzern zur Verfügung steht. In den Abschnitten "Verwenden des LoginView-Steuerelements" und "Programmgesteuertes Einschränken der Funktionalität" erfahren Sie, wie Sie diese Features basierend auf der Rolle des besuchenden Benutzers aktivieren oder deaktivieren.

Hinweis

Die ASP.NET Seite, die wir erstellen möchten, verwendet ein GridView-Steuerelement, um die Benutzerkonten 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 Anleitungen zum Einrichten dieser Seite, geht aber nicht darauf ein, 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 RoleBasedAuthorization.aspx Seite im Roles Ordner. Ziehen Sie eine GridView von der Seite auf die Designer, und legen Sie sie ID auf festUserGrid. In einem Moment schreiben wir Code, der das Membershipaufruft.GetAllUsers und bindet das resultierende MembershipUserCollection Objekt an die GridView. Enthält MembershipUserCollection ein Objekt für jedes Benutzerkonto im System. MembershipUser Objekte verfügen über Eigenschaften wie UserNameuswEmailLastLoginDate.MembershipUser

Bevor wir den Code schreiben, der die Benutzerkonten an das Raster bindet, definieren wir zunächst die Felder von GridView. Klicken Sie im Smarttag von GridView auf den Link "Spalten bearbeiten", um das Dialogfeld Felder zu starten (siehe Abbildung 6). Deaktivieren Sie hier das Kontrollkästchen "Felder automatisch generieren" in der linken unteren Ecke. Da diese GridView Bearbeitungs- und Löschfunktionen enthalten soll, fügen Sie ein CommandField-Element hinzu, und legen Sie dessen ShowEditButton Eigenschaften und ShowDeleteButton auf True fest. Fügen Sie als Nächstes vier Felder zum Anzeigen der UserNameEigenschaften , Email, LastLoginDateund Comment hinzu. Verwenden Sie boundField für die beiden schreibgeschützten Eigenschaften (UserName und LastLoginDate) und TemplateFields für die beiden bearbeitbaren Felder (Email und Comment).

Lassen Sie das erste BoundField die UserName -Eigenschaft anzeigen; legen Sie die HeaderText eigenschaften und DataField auf "UserName" fest. Dieses Feld kann nicht bearbeitet werden, daher legen Sie seine ReadOnly Eigenschaft auf True fest. Konfigurieren Sie das LastLoginDate BoundField, indem Sie es HeaderText auf "Letzte Anmeldung" und auf DataField "LastLoginDate" festlegen. Formatieren Sie die Ausgabe dieses BoundField so, dass nur das Datum (anstelle von Datum und Uhrzeit) angezeigt wird. Legen Sie dazu die Eigenschaft dieser BoundField-Eigenschaft HtmlEncode auf False und ihre DataFormatString Eigenschaft auf ""{0:d} fest. Legen Sie außerdem die ReadOnly Eigenschaft auf True fest.

Legen Sie die HeaderText Eigenschaften der beiden TemplateFields auf "Email" und "Comment" fest.

Die Felder von GridView können über das Dialogfeld Felder konfiguriert werden.

Abbildung 6: Die Felder von GridView können über das Dialogfeld Felder konfiguriert werden (Klicken Sie, um das bild in voller Größe anzuzeigen)

Nun müssen wir das und EditItemTemplate für die ItemTemplate TemplateFields "Email" und "Comment" definieren. Fügen Sie jedem von ItemTemplates ein Label-Websteuerelement hinzu, und binden Sie deren Text Eigenschaften an die Eigenschaften bzwComment. die Email Eigenschaften.

Fügen Sie für das TemplateField "Email" ein TextBox-Element mit dem Namen Email hinzuEditItemTemplate, und binden Sie seine Text Eigenschaft mithilfe der bidirektionalen Datenbindung an die Email -Eigenschaft. Fügen Sie einen RequiredFieldValidator und Einen RegularExpressionValidator hinzuEditItemTemplate, um sicherzustellen, dass ein Besucher, der die Email-Eigenschaft bearbeitet, eine gültige E-Mail-Adresse eingegeben hat. Fügen Sie für das TemplateField "Kommentar" ein mehrzeiliges TextBox-Element mit dem Namen Comment hinzu EditItemTemplate. Legen Sie die Eigenschaften und des TextBox-Objekts Columns auf 40 bzw. 4 fest, und binden Text Sie die Eigenschaft dann mithilfe der bidirektionalen Datenbindung an die Comment -Eigenschaft.Rows

Nach dem Konfigurieren dieser TemplateFields sollte ihr deklaratives Markup wie folgt aussehen:

<asp:TemplateField HeaderText="Email">
     <ItemTemplate>
          <asp:Label runat="server" ID="Label1" Text='<%# Eval("Email")%>'></asp:Label>

     </ItemTemplate>
     <EditItemTemplate>
          <asp:TextBox runat="server" ID="Email" Text='<%# Bind("Email")%>'></asp:TextBox>

          <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" 
               ControlToValidate="Email" Display="Dynamic"
               ErrorMessage="You must provide an email address."
               SetFocusOnError="True">*</asp:RequiredFieldValidator>

          <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server"
               ControlToValidate="Email" Display="Dynamic"
               ErrorMessage="The email address you have entered is not valid. Please fix 
               this and try again."
               SetFocusOnError="True"

               ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">*
          </asp:RegularExpressionValidator>
     </EditItemTemplate>
</asp:TemplateField>

<asp:TemplateField HeaderText="Comment">
     <ItemTemplate>
          <asp:Label runat="server" ID="Label2" Text='<%# Eval("Comment")%>'></asp:Label>

     </ItemTemplate>
     <EditItemTemplate>
          <asp:TextBox runat="server" ID="Comment" TextMode="MultiLine"
               Columns="40" Rows="4" Text='<%# Bind("Comment")%>'>

          </asp:TextBox>
     </EditItemTemplate>
</asp:TemplateField>

Beim Bearbeiten oder Löschen eines Benutzerkontos müssen wir den Eigenschaftswert dieses UserName Benutzers kennen. Legen Sie die GridView-Eigenschaft DataKeyNames auf "UserName" fest, damit diese Informationen über die GridView-Auflistung DataKeys verfügbar sind.

Fügen Sie schließlich der Seite ein ValidationSummary-Steuerelement hinzu, und legen Sie seine ShowMessageBox Eigenschaft auf True und seine ShowSummary Eigenschaft auf False fest. Mit diesen Einstellungen zeigt validationSummary eine clientseitige Warnung an, wenn der Benutzer versucht, ein Benutzerkonto mit einer fehlenden oder ungültigen E-Mail-Adresse zu bearbeiten.

<asp:ValidationSummary ID="ValidationSummary1"
               runat="server"
               ShowMessageBox="True"
               ShowSummary="False" />

Wir haben nun das deklarative Markup dieser Seite abgeschlossen. Unsere nächste Aufgabe besteht darin, den Satz von Benutzerkonten an die GridView zu binden. Fügen Sie der CodeBehind-Klasse der RoleBasedAuthorization.aspx Seite eine Methode mit dem Namen BindUserGrid hinzu, die das MembershipUserCollection zurückgegebene von Membership.GetAllUsers an die UserGrid GridView bindet. Rufen Sie diese Methode beim ersten Seitenbesuch aus dem Page_Load Ereignishandler auf.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
     If Not Page.IsPostBack Then
          BindUserGrid()
     End If
End Sub

Private Sub BindUserGrid()
     Dim allUsers As MembershipUserCollection = Membership.GetAllUsers()
     UserGrid.DataSource = allUsers
     UserGrid.DataBind()
End Sub

Wenn dieser Code vorhanden ist, besuchen Sie die Seite über einen Browser. Wie Abbildung 7 zeigt, sollten Sie eine GridView-Auflistungsinformationen zu jedem Benutzerkonto im System sehen.

UserGrid GridView listet Informationen zu jedem Benutzer im System auf.

Abbildung 7: GridView UserGrid listet Informationen zu jedem Benutzer im System auf (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Hinweis

Die UserGrid GridView listet alle Benutzer in einer nicht ausgelagerten Benutzeroberfläche auf. Diese einfache Rasterschnittstelle eignet sich nicht für Szenarien, in denen mehrere Dutzend oder mehr Benutzer vorhanden sind. Eine Option besteht darin, gridView so zu konfigurieren, dass das Paging aktiviert wird. Die Membership.GetAllUsers Methode verfügt über zwei Überladungen: eine, die keine Eingabeparameter akzeptiert und alle Benutzer zurückgibt, und eine, die ganzzahlige Werte für den Seitenindex und die Seitengröße übernimmt und nur die angegebene Teilmenge der Benutzer zurückgibt. Die zweite Überladung kann verwendet werden, um die Benutzer effizienter zu durchlaufen, da sie nur die genaue Teilmenge der Benutzerkonten und nicht alle von ihnen zurückgibt. Wenn Sie über Tausende von Benutzerkonten verfügen, sollten Sie eine filterbasierte Schnittstelle in Betracht ziehen, die nur die Benutzer anzeigt, deren Benutzername mit einem ausgewählten Zeichen beginnt, für instance. Die Membership.FindUsersByName Methode eignet sich ideal zum Erstellen einer filterbasierten Benutzeroberfläche. Wir werden uns das Erstellen einer solchen Schnittstelle in einem zukünftigen Tutorial ansehen.

Das GridView-Steuerelement bietet integrierte Bearbeitungs- und Löschunterstützung, wenn das Steuerelement an ein ordnungsgemäß konfiguriertes Datenquellensteuerelement wie SqlDataSource oder ObjectDataSource gebunden ist. Die UserGrid GridView ist jedoch programmgesteuert an die Daten gebunden. Daher müssen wir Code schreiben, um diese beiden Aufgaben auszuführen. Insbesondere müssen wir Ereignishandler für die GridView-Ereignisse RowEditing, RowCancelingEdit, , RowUpdatingund erstellen, die RowDeleting ausgelöst werden, wenn ein Besucher auf die Schaltflächen Bearbeiten, Abbrechen, Aktualisieren oder Löschen von GridView klickt.

Erstellen Sie zunächst die Ereignishandler für die GridView-Ereignisse RowEditing, RowCancelingEditund RowUpdating fügen Sie dann den folgenden Code hinzu:

Protected Sub UserGrid_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles UserGrid.RowEditing
     ' Set the grid's EditIndex and rebind the data

     UserGrid.EditIndex = e.NewEditIndex
     BindUserGrid()
End Sub

Protected Sub UserGrid_RowCancelingEdit(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCancelEditEventArgs) Handles UserGrid.RowCancelingEdit
     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub
    
Protected Sub UserGrid_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles UserGrid.RowUpdating
     ' Exit if the page is not valid
     If Not Page.IsValid Then
          Exit Sub
     End If

     ' Determine the username of the user we are editing
     Dim UserName As String = UserGrid.DataKeys(e.RowIndex).Value.ToString()

     ' Read in the entered information and update the user
     Dim EmailTextBox As TextBox = CType(UserGrid.Rows(e.RowIndex).FindControl("Email"),TextBox)
     Dim CommentTextBox As TextBox= CType(UserGrid.Rows(e.RowIndex).FindControl("Comment"),TextBox)

     ' Return information about the user
     Dim UserInfo As MembershipUser = Membership.GetUser(UserName)

     ' Update the User account information
     UserInfo.Email = EmailTextBox.Text.Trim()
     UserInfo.Comment = CommentTextBox.Text.Trim()

     Membership.UpdateUser(UserInfo)

     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub

Die RowEditing Ereignishandler und RowCancelingEdit legen einfach die GridView-Eigenschaft EditIndex fest und binden dann die Liste der Benutzerkonten erneut an das Raster. Das Interessante geschieht im RowUpdating Ereignishandler. Dieser Ereignishandler stellt zunächst sicher, dass die Daten gültig sind, und greift dann den UserName Wert des bearbeiteten Benutzerkontos aus der DataKeys Sammlung ab. Anschließend Email wird programmgesteuert auf die Textfelder und Comment in den beiden TemplateFields EditItemTemplate verwiesen. Ihre Text Eigenschaften enthalten die bearbeitete E-Mail-Adresse und den Kommentar.

Um ein Benutzerkonto über die Mitgliedschafts-API zu aktualisieren, müssen wir zuerst die Benutzerinformationen abrufen, was wir über einen Aufruf von tun Membership.GetUser(userName). Die Eigenschaften des zurückgegebenen MembershipUser Objekts Email und Comment werden dann mit den Werten aktualisiert, die über die Bearbeitungsschnittstelle in die beiden TextBoxes eingegeben werden. Schließlich werden diese Änderungen mit einem Aufruf von Membership.UpdateUsergespeichert. Der RowUpdating Ereignishandler wird abgeschlossen, indem die GridView auf die Schnittstelle vor der Bearbeitung zurückgesetzt wird.

Erstellen Sie als Nächstes den RowDeleting RowDeleting-Ereignishandler, und fügen Sie dann den folgenden Code hinzu:

Protected Sub UserGrid_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles UserGrid.RowDeleting

     ' Determine the username of the user we are editing
     Dim UserName As String = UserGrid.DataKeys(e.RowIndex).Value.ToString()

     ' Delete the user
     Membership.DeleteUser(UserName)

     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub

Der obige Ereignishandler beginnt mit dem Abrufen des UserName Werts aus der GridView-AuflistungDataKeys. Dieser UserName Wert wird dann an die Methode der Membership-Klasse DeleteUserübergeben. Die DeleteUser -Methode löscht das Benutzerkonto aus dem System, einschließlich zugehöriger Mitgliedschaftsdaten (z. B. den Rollen, zu der dieser Benutzer gehört). Nach dem Löschen des Benutzers wird das Raster auf -1 festgelegt (falls der Benutzer auf Löschen geklickt hat, während sich eine andere Zeile im Bearbeitungsmodus EditIndex befand) und die BindUserGrid Methode aufgerufen wird.

Hinweis

Die Schaltfläche Löschen erfordert keine Bestätigung des Benutzers, bevor das Benutzerkonto gelöscht wird. Ich ermutige Sie, eine Form der Benutzerbestätigung hinzuzufügen, um die Wahrscheinlichkeit zu mindern, dass ein Konto versehentlich gelöscht wird. Eine der einfachsten Möglichkeiten zum Bestätigen einer Aktion ist ein clientseitiges Bestätigungsdialogfeld. Weitere Informationen zu diesem Verfahren finden Sie unter Hinzufügen Client-Side Bestätigung beim Löschen.

Vergewissern Sie sich, dass diese Seite wie erwartet funktioniert. Sie sollten in der Lage sein, die E-Mail-Adresse und den Kommentar eines beliebigen Benutzers zu bearbeiten und jedes Benutzerkonto zu löschen. Da die RoleBasedAuthorization.aspx Seite für alle Benutzer zugänglich ist, kann jeder Benutzer – auch anonyme Besucher – diese Seite besuchen und Benutzerkonten bearbeiten und löschen! Lassen Sie uns diese Seite aktualisieren, sodass nur Benutzer in den Rollen "Supervisors" und "Administratoren" die E-Mail-Adresse und den Kommentar eines Benutzers bearbeiten können und nur Administratoren ein Benutzerkonto löschen können.

Im Abschnitt "Verwenden des LoginView-Steuerelements" wird die Verwendung des LoginView-Steuerelements erläutert, um anweisungen anzuzeigen, die für die Rolle des Benutzers gelten. Wenn eine Person in der Rolle Administratoren diese Seite besucht, werden Anweisungen zum Bearbeiten und Löschen von Benutzern angezeigt. Wenn ein Benutzer in der Rolle "Supervisors" diese Seite erreicht, werden Anweisungen zum Bearbeiten von Benutzern angezeigt. Wenn der Besucher anonym ist oder nicht in der Rolle "Vorgesetzte" oder "Administratoren" tätig ist, wird eine Meldung angezeigt, in der erklärt wird, dass er Benutzerkontoinformationen nicht bearbeiten oder löschen kann. Im Abschnitt "Programmgesteuerte Einschränkung der Funktionalität" schreiben wir Code, der die Schaltflächen Bearbeiten und Löschen basierend auf der Rolle des Benutzers programmgesteuert ein- oder ausblendet.

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, aber das LoginView-Steuerelement kann auch verwendet werden, um verschiedene Markups basierend auf den Rollen des Benutzers anzuzeigen. Verwenden Sie ein LoginView-Steuerelement, um verschiedene Anweisungen basierend auf der Rolle des besuchenden Benutzers anzuzeigen.

Beginnen Sie mit dem Hinzufügen einer LoginView über der UserGrid GridView. Wie bereits erläutert, verfügt das LoginView-Steuerelement über zwei integrierte Vorlagen: AnonymousTemplate und LoggedInTemplate. Geben Sie in beiden Vorlagen eine kurze Nachricht ein, die den Benutzer darüber informiert, dass er keine Benutzerinformationen bearbeiten oder löschen kann.

<asp:LoginView ID="LoginView1" runat="server">
     <LoggedInTemplate>
          You are not a member of the Supervisors or Administrators roles. Therefore you
           cannot edit or delete any user information.
     </LoggedInTemplate>
     <AnonymousTemplate>

          You are not logged into the system. Therefore you cannot edit or delete any user
           information.
     </AnonymousTemplate>
</asp:LoginView>

Zusätzlich zu und AnonymousTemplateLoggedInTemplatekann das LoginView-Steuerelement RoleGroups enthalten, bei denen es sich um rollenspezifische Vorlagen handelt. Jede RoleGroup enthält eine einzelne Eigenschaft, die angibt, Rolesauf welche Rollen die RoleGroup angewendet wird. Die Roles Eigenschaft kann auf eine einzelne Rolle (z. B. "Administratoren") oder auf eine durch Trennzeichen getrennte Liste von Rollen (z. B. "Administratoren, Vorgesetzte") festgelegt werden.

Klicken Sie zum Verwalten der Rollengruppen im Smarttag des Steuerelements auf den Link "Rollengruppen bearbeiten", um den Rollengruppensammlungs-Editor aufzurufen. Fügen Sie zwei neue RoleGroups hinzu. Legen Sie die Eigenschaft der ersten RoleGroup Roles auf "Administratoren" und die zweite auf "Supervisors" fest.

Verwalten der Role-Specific Vorlagen von LoginView über den RoleGroup-Sammlungs-Editor

Abbildung 8: Verwalten der Role-Specific-Vorlagen der LoginView über den RoleGroup-Sammlungs-Editor (Klicken Sie hier, um das vollständige Bild anzuzeigen)

Klicken Sie auf OK, um den Rollengruppensammlungs-Editor zu schließen. dadurch wird das deklarative Markup von LoginView aktualisiert, soweit es einen Abschnitt mit einem <RoleGroups><asp:RoleGroup> untergeordneten Element für jede RoleGroup enthält, die im RoleGroup-Sammlungs-Editor definiert ist. Darüber hinaus enthält die Dropdownliste "Ansichten" im Smarttag der LoginView, in der zunächst nur das AnonymousTemplate und LoggedInTemplate aufgeführt wurde, nun auch die hinzugefügten Rollengruppen.

Bearbeiten Sie die Rollengruppen, sodass Benutzern in der Rolle "Supervisors" Anweisungen zum Bearbeiten von Benutzerkonten angezeigt werden, während Benutzern in der Rolle "Administratoren" Anweisungen zum Bearbeiten und Löschen angezeigt werden. Nachdem Sie diese Änderungen vorgenommen haben, sollte das deklarative Markup Ihres LoginView-Steuerelements wie folgt aussehen.

<asp:LoginView ID="LoginView1" runat="server">
     <RoleGroups>
          <asp:RoleGroup Roles="Administrators">

               <ContentTemplate>
                    As an Administrator, you may edit and delete user accounts. 
                    Remember: With great power comes great responsibility!
               </ContentTemplate>
          </asp:RoleGroup>
          <asp:RoleGroup Roles="Supervisors">
               <ContentTemplate>
                    As a Supervisor, you may edit users&#39; Email and Comment information. 
                    Simply click the Edit button, make your changes, and then click Update.
               </ContentTemplate>

          </asp:RoleGroup>
     </RoleGroups>
     <LoggedInTemplate>
          You are not a member of the Supervisors or Administrators roles. 
          Therefore you cannot edit or delete any user information.
     </LoggedInTemplate>
     </AnonymousTemplate>
          You are not logged into the system. 
          Therefore you cannot edit or delete any user information.
     </AnonymousTemplate>
</asp:LoginView>

Nachdem Sie diese Änderungen vorgenommen haben, speichern Sie die Seite, und besuchen Sie sie dann über einen Browser. Besuchen Sie zuerst die Seite als anonymer Benutzer. Ihnen sollte die Meldung angezeigt werden: "Sie sind nicht beim System angemeldet. Daher können Sie keine Benutzerinformationen bearbeiten oder löschen." Melden Sie sich dann als authentifizierter Benutzer an, der sich jedoch weder in der Rolle "Supervisors" noch "Administratoren" befindet. Dieses Mal sollte die Meldung angezeigt werden: "Sie sind kein Mitglied der Rolle Vorgesetzte oder Administratoren. Daher können Sie keine Benutzerinformationen bearbeiten oder löschen."

Melden Sie sich als Nächstes als Benutzer an, der Mitglied der Rolle "Supervisors" ist. Dieses Mal sollte die rollenspezifische Meldung Supervisors angezeigt werden (siehe Abbildung 9). Wenn Sie sich als Benutzer in der Rolle "Administratoren" anmelden, sollte die Meldung Administratorrollenspezifische Meldung angezeigt werden (siehe Abbildung 10).

Bruce wird den Vorgesetzten Role-Specific Nachricht angezeigt.

Abbildung 9: Bruce wird die Role-Specific-Nachricht von Supervisors angezeigt (Klicken Sie, um das bild in voller Größe anzuzeigen)

Tito wird die Administrator-Role-Specific-Nachricht angezeigt

Abbildung 10: Tito zeigt die Meldung "Administratoren Role-Specific" (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Wie die Screenshots in Abbildungen 9 und 10 zeigen, rendert die LoginView nur eine Vorlage, auch wenn mehrere Vorlagen angewendet werden. Bruce und Tito sind beide Benutzer angemeldet, aber die LoginView rendert nur die übereinstimmende RoleGroup und nicht die LoggedInTemplate. Darüber hinaus gehört Tito sowohl zur Rolle Administratoren als auch zu den Vorgesetzten, aber das LoginView-Steuerelement rendert die rollespezifische Vorlage Administratoren anstelle der Vorgesetzten.

Abbildung 11 veranschaulicht den Workflow, der vom LoginView-Steuerelement verwendet wird, um zu bestimmen, welche Vorlage gerendert werden soll. Beachten Sie, dass, wenn mehr als eine RoleGroup angegeben ist, die LoginView-Vorlage die erste RoleGroup rendert, die übereinstimmt. Mit anderen Worten, wenn wir die Supervisors RoleGroup als erste Rollengruppe und die Administratoren als zweite platziert hätten, würde Tito diese Seite besuchen, die Meldung Supervisors angezeigt.

Der Workflow des LoginView-Steuerelements zum Bestimmen der zu rendernden Vorlage

Abbildung 11: Workflow des LoginView-Steuerelements zum Bestimmen der zu rendernden Vorlage (Klicken, um das bild in voller Größe anzuzeigen)

Programmgesteuerte Einschränkung der Funktionalität

Während das LoginView-Steuerelement verschiedene Anweisungen basierend auf der Rolle des Benutzers anzeigt, der die Seite besucht, bleiben die Schaltflächen Bearbeiten und Abbrechen für alle sichtbar. Wir müssen die Schaltflächen Bearbeiten und Löschen programmgesteuert für anonyme Besucher und Benutzer ausblenden, die sich weder in der Rolle "Supervisors" noch "Administratoren" befinden. Wir müssen die Schaltfläche Löschen für alle ausblenden, die kein Administrator sind. Um dies zu erreichen, schreiben wir ein wenig Code, der programmgesteuert auf die Edit and Delete LinkButtons von CommandField verweist und deren Visible Eigenschaften bei Bedarf auf Falsefestlegt.

Die einfachste Möglichkeit, programmgesteuert auf Steuerelemente in einem CommandField zu verweisen, besteht darin, sie zuerst in eine Vorlage zu konvertieren. Klicken Sie dazu im Smarttag von GridView auf den Link "Spalten bearbeiten", wählen Sie das CommandField aus der Liste der aktuellen Felder aus, und klicken Sie auf den Link "Dieses Feld in ein TemplateField konvertieren". Dadurch wird das CommandField-Objekt in ein TemplateField-Objekt mit ItemTemplate und EditItemTemplateumgewandelt. Enthält ItemTemplate die LinkButtons bearbeiten und löschen, während die EditItemTemplate LinkButtons Aktualisieren und Abbrechen enthält.

Konvertieren des Befehlsfelds in ein TemplateField

Abbildung 12: Konvertieren des Befehlsfelds in ein TemplateField (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Aktualisieren Sie die LinkButtons bearbeiten und löschen in , ItemTemplateund legen Sie ihre ID Eigenschaften auf Werte von EditButton bzw DeleteButton. fest.

<asp:TemplateField ShowHeader="False">
     <EditItemTemplate>
          <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True" 
               CommandName="Update" Text="Update"></asp:LinkButton>

           <asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
               CommandName="Cancel" Text="Cancel"></asp:LinkButton>

     </EditItemTemplate>
     <ItemTemplate>
          <asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" 
               CommandName="Edit" Text="Edit"></asp:LinkButton>

           <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
               CommandName="Delete" Text="Delete"></asp:LinkButton>

     </ItemTemplate>
</asp:TemplateField>

Wenn Daten an die GridView gebunden sind, zählt gridView die Datensätze in seiner DataSource Eigenschaft auf und generiert ein entsprechendes GridViewRow Objekt. Während jedes GridViewRow Objekt erstellt wird, wird das RowCreated Ereignis ausgelöst. Um die Schaltflächen Bearbeiten und Löschen für nicht autorisierte Benutzer auszublenden, müssen wir einen Ereignishandler für dieses Ereignis erstellen und programmgesteuert auf die LinkButtons Bearbeiten und Löschen verweisen und deren Visible Eigenschaften entsprechend festlegen.

Erstellen Sie einen Ereignishandler für das RowCreated Ereignis, und fügen Sie dann den folgenden Code hinzu:

Protected Sub UserGrid_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles UserGrid.RowCreated
     If e.Row.RowType = DataControlRowType.DataRow AndAlso e.Row.RowIndex <> UserGrid.EditIndex Then
          ' Programmatically reference the Edit and Delete LinkButtons
          Dim EditButton As LinkButton = CType(e.Row.FindControl("EditButton"), LinkButton)

          Dim DeleteButton As LinkButton = CType(e.Row.FindControl("DeleteButton"), LinkButton)

          EditButton.Visible = (User.IsInRole("Administrators") OrElse User.IsInRole("Supervisors"))
          DeleteButton.Visible = User.IsInRole("Administrators")
     End If
End Sub

Beachten Sie, dass das RowCreated Ereignis für alle GridView-Zeilen ausgelöst wird, einschließlich der Kopfzeile, der Fußzeile, der Pagerschnittstelle usw. Wir möchten nur programmgesteuert auf die LinkButtons Bearbeiten und Löschen verweisen, wenn es sich um eine Datenzeile handelt, die sich nicht im Bearbeitungsmodus befindet (da die Zeile im Bearbeitungsmodus die Schaltflächen Aktualisieren und Abbrechen anstelle von Bearbeiten und Löschen aufweist). Diese Überprüfung wird von der If -Anweisung behandelt.

Wenn es sich um eine Datenzeile handelt, die sich nicht im Bearbeitungsmodus befindet, wird auf die LinkButtons Bearbeiten und Löschen verwiesen, und ihre Visible Eigenschaften werden basierend auf den booleschen Werten festgelegt, die von der Methode des UserIsInRole(roleName) Objekts zurückgegeben werden. Das User -Objekt verweist auf den Prinzipal, der RoleManagerModulevon erstellt wurde. Daher verwendet die IsInRole(roleName) Methode die Rollen-API, um zu bestimmen, ob der aktuelle Besucher zu roleName gehört.

Hinweis

Wir hätten die Roles-Klasse direkt verwenden und den Aufruf User.IsInRole(roleName) von durch einen Aufruf der Roles.IsUserInRole(roleName) -Methode ersetzen können. Ich habe mich in diesem Beispiel für die Verwendung der Methode des IsInRole(roleName) Prinzipals entschieden, da sie effizienter ist als die direkte Verwendung der Rollen-API. Weiter oben in diesem Tutorial haben wir den Rollen-Manager so konfiguriert, dass er die Rollen des Benutzers in einem Cookie zwischenspeichert. Diese zwischengespeicherten Cookiedaten werden nur verwendet, wenn die Methode des IsInRole(roleName) Prinzipals aufgerufen wird. Direkte Aufrufe der Rollen-API beinhalten immer einen Trip zum Rollenspeicher. Auch wenn Rollen nicht in einem Cookie zwischengespeichert werden, ist das Aufrufen der Methode des Prinzipalobjekts IsInRole(roleName) in der Regel effizienter, da beim ersten Aufruf während einer Anforderung die Ergebnisse zwischengespeichert werden. Die Rollen-API führt dagegen keine Zwischenspeicherung durch. Da das RowCreated Ereignis für jede Zeile in GridView einmal ausgelöst wird, umfasst die Verwendung User.IsInRole(roleName) nur eine Fahrt zum Rollenspeicher, während Roles.IsUserInRole(roleName)N-Fahrten erforderlich sind, wobei N die Anzahl der im Raster angezeigten Benutzerkonten darstellt.

Die Eigenschaft der Visible Schaltfläche Bearbeiten wird auf True festgelegt, wenn sich der Benutzer, der diese Seite besucht, in der Rolle "Administratoren" oder "Supervisors" befindet. Andernfalls ist sie auf Falsefestgelegt. Die Eigenschaft der Visible Schaltfläche Löschen ist nur auf True festgelegt, wenn sich der Benutzer in der Rolle "Administratoren" befindet.

Testen Sie diese Seite über einen Browser. Wenn Sie die Seite als anonymer Besucher oder als Benutzer besuchen, der weder Supervisor noch Administrator ist, ist das CommandField leer. es ist weiterhin vorhanden, aber als dünner Streifen ohne die Schaltflächen Bearbeiten oder Löschen.

Hinweis

Es ist möglich, das CommandField vollständig auszublenden, wenn ein Nicht-Supervisor und ein Nicht-Administrator die Seite besucht. Ich belasse dies als Übung für den Leser.

Die Schaltflächen Bearbeiten und Löschen sind für Nicht-Vorgesetzte und Nichtadministratoren ausgeblendet.

Abbildung 13: Die Schaltflächen Bearbeiten und Löschen sind für Nicht-Vorgesetzte und Nichtadministratoren ausgeblendet (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Wenn ein Benutzer, der der Rolle "Supervisors" (aber nicht der Rolle "Administratoren") angehört, besucht, wird nur die Schaltfläche Bearbeiten angezeigt.

Während die Schaltfläche Bearbeiten für Vorgesetzte verfügbar ist, ist die Schaltfläche Löschen ausgeblendet.

Abbildung 14: Während die Schaltfläche Bearbeiten für Supervisors verfügbar ist, ist die Schaltfläche "Löschen" ausgeblendet (Klicken Sie hier, um das bild in voller Größe anzuzeigen).

Und wenn ein Administrator besucht, hat er Zugriff auf die Schaltflächen Bearbeiten und Löschen.

Die Schaltflächen Bearbeiten und Löschen sind nur für Administratoren verfügbar.

Abbildung 15: Die Schaltflächen Bearbeiten und Löschen sind nur für Administratoren verfügbar (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Schritt 3: Anwenden Role-Based Autorisierungsregeln auf Klassen und Methoden

In Schritt 2 haben wir die Bearbeitungsfunktionen auf Benutzer in den Rollen "Supervisors" und "Administratoren" beschränkt und funktionen nur auf Administratoren gelöscht. Dies wurde erreicht, indem die zugehörigen Benutzeroberflächenelemente für nicht autorisierte Benutzer mithilfe programmgesteuerter Techniken ausgeblendet wurden. Solche Maßnahmen garantieren nicht, dass ein nicht autorisierter Benutzer keine privilegierte Aktion ausführen kann. Möglicherweise gibt es Elemente der Benutzeroberfläche, die später hinzugefügt werden oder die wir vergessen haben, für nicht autorisierte Benutzer auszublenden. Oder ein Hacker kann eine andere Möglichkeit entdecken, um die ASP.NET Seite zu erhalten, um die gewünschte Methode auszuführen.

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 berechtigungen verfügt. Das PrincipalPermission -Attribut stellt einen Mechanismus bereit, über den wir diese Regeln definieren können.

Wir haben uns die Verwendung des PrincipalPermission Attributs im Tutorial "Benutzerbasierte Autorisierung" angesehen. Insbesondere haben wir gesehen, wie der GridView-Ereignishandler SelectedIndexChanged und RowDeleting der Ereignishandler so gestaltet werden, dass sie nur von authentifizierten Benutzern bzw. Tito ausgeführt werden konnten. Das PrincipalPermission Attribut funktioniert genauso gut mit Rollen.

Wir veranschaulichen die Verwendung des PrincipalPermission Attributs RowUpdating für die GridView- und RowDeleting -Ereignishandler, um die Ausführung für nicht autorisierte Benutzer zu verhindern. Alles, was wir tun müssen, ist, das entsprechende Attribut zu jeder Funktionsdefinition hinzuzufügen:

<PrincipalPermission(SecurityAction.Demand, Role:="Administrators")>_
<PrincipalPermission(SecurityAction.Demand, Role:="Supervisors")>_
Protected Sub UserGrid_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles UserGrid.RowUpdating
     ...
End Sub

<PrincipalPermission(SecurityAction.Demand, Role:="Administrators")>_
Protected Sub UserGrid_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles UserGrid.RowDeleting
     ...
End Sub

Das -Attribut für den RowUpdating Ereignishandler legt fest, dass nur Benutzer in der Rolle Administratoren oder Betreuer den Ereignishandler ausführen können, wobei die Ausführung als Attribut für den RowDeleting Ereignishandler auf Benutzer in der Rolle Administratoren beschränkt ist.

Hinweis

Das PrincipalPermission Attribut wird als Klasse im System.Security.Permissions Namespace dargestellt. Fügen Sie am Anfang Ihrer CodeBehind-Klassendatei eine Imports System.Security.Permissions Anweisung hinzu, um diesen Namespace zu importieren.

Wenn ein Nicht-Administrator versucht, den RowDeleting Ereignishandler auszuführen, oder wenn ein Nicht-Supervisor oder Nicht-Administrator versucht, den RowUpdating 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 16: Wenn der Sicherheitskontext nicht zum Ausführen der Methode autorisiert ist, wird ein SecurityException ausgelöst (Klicken Sie, um das vollständige Bild anzuzeigen)

Neben ASP.NET Seiten verfügen viele Anwendungen auch über eine Architektur, die verschiedene Ebenen wie Geschäftslogik und Datenzugriffsebenen umfasst. 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 auch 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 unter Scott Guthries Blogeintrag Hinzufügen von Autorisierungsregeln zu Geschäfts- und Datenebenen mit PrincipalPermissionAttributes.

Zusammenfassung

In diesem Tutorial haben wir uns mit der Angabe grober und feiner Autorisierungsregeln basierend auf den Rollen des Benutzers befasst. ASP. Die URL-Autorisierungsfunktion von NET ermöglicht es einem Seitenentwickler, anzugeben, welche Identitäten der Zugriff auf welche Seiten zulässig oder verweigert wird. Wie wir im Tutorial " Benutzerbasierte Autorisierung" gezeigt haben, können URL-Autorisierungsregeln auf Benutzerbasis angewendet werden. Sie können auch rollenweise angewendet werden, wie wir in Schritt 1 dieses Tutorials gezeigt haben.

Differenzierte Autorisierungsregeln können deklarativ oder programmgesteuert angewendet werden. In Schritt 2 haben wir die Verwendung des RoleGroups-Features des LoginView-Steuerelements untersucht, um eine andere Ausgabe basierend auf den Rollen des besuchenden Benutzers zu rendern. Außerdem wurde untersucht, wie Sie programmgesteuert ermitteln können, ob ein Benutzer zu einer bestimmten Rolle gehört und wie die Funktionalität der Seite entsprechend angepasst werden kann.

Viel Spaß beim Programmieren!

Weitere Informationen

Weitere Informationen zu den in diesem Tutorial erläuterten 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 Stunden. Scott kann unter mitchell@4guysfromrolla.com oder über seinen Blog unter http://ScottOnWriting.NETerreicht werden.

Besonderen Dank an...

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Zu den leitenden Prüfern für dieses Tutorial gehören Suchi Banerjee und Teresa Murphy. Möchten Sie meine anstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie mir eine Zeile unter mitchell@4GuysFromRolla.com