Autoryzacja oparta na rolach (VB)

Autor : Scott Mitchell

Uwaga

Od czasu napisania tego artykułu dostawcy członkostwa ASP.NET zostali zastąpioni przez ASP.NET Identity. Zdecydowanie zalecamy aktualizowanie aplikacji w celu korzystania z platformy ASP.NET Identity , a nie dostawców członkostwa w momencie pisania tego artykułu. ASP.NET Identity ma wiele zalet w porównaniu z systemem członkostwa ASP.NET, w tym :

  • Lepsza wydajność
  • Ulepszona rozszerzalność i możliwość testowania
  • Obsługa uwierzytelniania OAuth, OpenID Connect i uwierzytelniania dwuskładnikowego
  • Obsługa tożsamości opartej na oświadczeniach
  • Lepsze współdziałanie z platformą ASP.Net Core

Pobierz kod lub pobierz plik PDF

Ten samouczek rozpoczyna się od zapoznania się ze sposobem kojarzenia ról użytkownika z jego kontekstem zabezpieczeń. Następnie analizuje sposób stosowania reguł autoryzacji adresów URL opartych na rolach. Następnie przyjrzymy się używaniu środków deklaratywnych i programowych do zmiany wyświetlanych danych i funkcjonalności oferowanych przez stronę ASP.NET.

Wprowadzenie

W samouczku autoryzacji opartej na użytkownikach pokazano, jak używać autoryzacji adresu URL w celu określenia, co użytkownicy mogą odwiedzać określony zestaw stron. W przypadku niewielkiej ilości znaczników w programie Web.configmożemy poinstruować ASP.NET, aby zezwolić tylko uwierzytelnieni użytkownikom na odwiedzanie strony. Możemy też dyktować, że tylko użytkownicy Tito i Bob byli dozwoloni lub wskazać, że wszyscy uwierzytelnieni użytkownicy z wyjątkiem Sam byli dozwoloni.

Oprócz autoryzacji adresów URL przyjrzeliśmy się również technikom deklaratywnym i programowym kontrolowania wyświetlanych danych oraz funkcjonalności oferowanych przez stronę na podstawie odwiedzania użytkownika. W szczególności utworzyliśmy stronę zawierającą zawartość bieżącego katalogu. Każda osoba może odwiedzić tę stronę, ale tylko uwierzytelnieni użytkownicy mogą wyświetlać zawartość plików i tylko Tito może usunąć pliki.

Stosowanie reguł autoryzacji w oparciu o użytkownika może wzrosnąć do koszmaru księgowania. Bardziej przystępnym podejściem jest użycie autoryzacji opartej na rolach. Dobrą wiadomością jest to, że narzędzia dostępne do stosowania reguł autoryzacji działają równie dobrze z rolami, jak w przypadku kont użytkowników. Reguły autoryzacji adresów URL mogą określać role zamiast użytkowników. Kontrolka LoginView, która renderuje różne dane wyjściowe dla uwierzytelnionych i anonimowych użytkowników, można skonfigurować tak, aby wyświetlała inną zawartość na podstawie ról zalogowanego użytkownika. Interfejs API ról zawiera metody określania ról zalogowanego użytkownika.

Ten samouczek rozpoczyna się od zapoznania się ze sposobem kojarzenia ról użytkownika z jego kontekstem zabezpieczeń. Następnie analizuje sposób stosowania reguł autoryzacji adresów URL opartych na rolach. Następnie przyjrzymy się używaniu środków deklaratywnych i programowych do zmiany wyświetlanych danych i funkcjonalności oferowanych przez stronę ASP.NET. Zaczynamy!

Opis sposobu, w jaki role są skojarzone z kontekstem zabezpieczeń użytkownika

Za każdym razem, gdy żądanie wprowadza potok ASP.NET jest skojarzony z kontekstem zabezpieczeń, który zawiera informacje identyfikujące osoby żądającej. W przypadku korzystania z uwierzytelniania formularzy bilet uwierzytelniania jest używany jako token tożsamości. Jak omówiono w samouczku Omówienie uwierzytelniania formularzy , FormsAuthenticationModule jest odpowiedzialny za określenie tożsamości osoby żądającej, która odbywa się podczas AuthenticateRequest zdarzenia.

Jeśli zostanie znaleziony prawidłowy, wygasły bilet uwierzytelniania, FormsAuthenticationModule dekoduje go w celu ustalenia tożsamości osoby żądającej. Tworzy nowy GenericPrincipal obiekt i przypisuje go do HttpContext.User obiektu . Celem podmiotu zabezpieczeń, takiego jak GenericPrincipal, jest zidentyfikowanie nazwy uwierzytelnionego użytkownika i ról, do których należy. Ten cel jest widoczny przez fakt, że wszystkie obiekty zabezpieczeń mają Identity właściwość i metodę IsInRole(roleName) . Obiekt FormsAuthenticationModule, jednak nie jest zainteresowany rejestrowaniem informacji o roli, a GenericPrincipal tworzony obiekt nie określa żadnych ról.

Jeśli platforma ról jest włączona, RoleManagerModule moduł HTTP krok po i FormsAuthenticationModule identyfikuje uwierzytelnione role użytkownika podczas PostAuthenticateRequest zdarzenia, które jest uruchamiane po AuthenticateRequest zdarzeniu. Jeśli żądanie pochodzi od uwierzytelnionego użytkownika, RoleManagerModule zastępuje GenericPrincipal obiekt utworzony przez FormsAuthenticationModule obiekt i zastępuje go obiektemRolePrincipal . Klasa RolePrincipal używa interfejsu API ról do określania ról, do których należy użytkownik.

Rysunek 1 przedstawia przepływ pracy potoku ASP.NET podczas korzystania z uwierzytelniania formularzy i platformy role. Funkcja FormsAuthenticationModule wykonuje najpierw, identyfikuje użytkownika za pośrednictwem biletu uwierzytelniania i tworzy nowy GenericPrincipal obiekt. Następnie kroki opisane w metodzie RoleManagerModule i zastępują GenericPrincipal obiekt obiektem RolePrincipal .

Jeśli anonimowy użytkownik odwiedza witrynę, ani FormsAuthenticationModule obiekt nie RoleManagerModule tworzy obiektu głównego.

Zdarzenia potoku ASP.NET dla uwierzytelnionego użytkownika podczas korzystania z uwierzytelniania formularzy i struktury ról

Rysunek 1. Zdarzenia potoku ASP.NET dla uwierzytelnionego użytkownika podczas korzystania z uwierzytelniania formularzy i struktury ról (kliknij, aby wyświetlić obraz pełnowymiarowy)

RolePrincipal Metoda obiektu wywołuje metodę IsInRole(roleName)Roles.GetRolesForUser aby uzyskać role dla użytkownika w celu określenia, czy użytkownik jest członkiem roleName. W przypadku korzystania z SqlRoleProviderprogramu powoduje to wysłanie zapytania do bazy danych magazynu ról. W przypadku korzystania z reguł RolePrincipalautoryzacji adresów URL opartych na rolach metoda będzie wywoływana IsInRole na każdym żądaniu do strony chronionej przez reguły autoryzacji adresów URL oparte na rolach. Zamiast wyszukiwać informacje o rolach w bazie danych na każdym żądaniu, Roles platforma zawiera opcję buforowania ról użytkownika w pliku cookie.

Jeśli platforma Role jest skonfigurowana do buforowania ról użytkownika w pliku cookie, RoleManagerModule program tworzy plik cookie podczas zdarzenia potoku EndRequestASP.NET. Ten plik cookie jest używany w kolejnych żądaniach w obiekcie PostAuthenticateRequest, czyli podczas RolePrincipal tworzenia obiektu. Jeśli plik cookie jest prawidłowy i nie wygasł, dane w pliku cookie są analizowane i używane do wypełniania ról użytkownika, co pozwala zaoszczędzić RolePrincipal konieczność wywołania Roles klasy w celu określenia ról użytkownika. Rysunek 2 przedstawia ten przepływ pracy.

Informacje o roli użytkownika mogą być przechowywane w pliku cookie w celu zwiększenia wydajności

Rysunek 2. Informacje o roli użytkownika mogą być przechowywane w pliku cookie w celu zwiększenia wydajności (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Domyślnie mechanizm plików cookie pamięci podręcznej roli jest wyłączony. Można ją włączyć za pomocą znacznika <roleManager>konfiguracji w pliku Web.config. Omówiliśmy używanie <roleManager> elementu do określania dostawców ról w samouczku Tworzenie ról i zarządzanie nimi , więc w pliku aplikacji Web.config powinien już być używany ten element. Ustawienia plików cookie pamięci podręcznej roli są określane jako atrybuty <roleManager>elementu ; i są sumowane w tabeli 1.

Uwaga

Ustawienia konfiguracji wymienione w tabeli 1 określają właściwości wynikowego pliku cookie pamięci podręcznej roli. Aby uzyskać więcej informacji na temat plików cookie, sposobu ich działania i ich różnych właściwości, przeczytaj ten samouczek dotyczący plików cookie.

Właściwość Opis
cacheRolesInCookie Wartość logiczna wskazująca, czy buforowanie plików cookie jest używane. Wartość domyślna to false.
cookieName Nazwa pliku cookie pamięci podręcznej roli. Wartość domyślna to ". ASPXROLES".
cookiePath Ścieżka pliku cookie nazwy ról. Atrybut path umożliwia deweloperowi ograniczenie zakresu pliku cookie do określonej hierarchii katalogów. Wartość domyślna to "/", która informuje przeglądarkę o wysłaniu pliku cookie biletu uwierzytelniania do dowolnego żądania wysłanego do domeny.
cookieProtection Wskazuje, jakie techniki są używane do ochrony pliku cookie pamięci podręcznej roli. Dozwolone wartości to: All (wartość domyślna); Encryption; None; i Validation.md)

| cookieRequireSSL | Wartość logiczna wskazująca, czy do przesyłania pliku cookie uwierzytelniania jest wymagane połączenie SSL. Wartość domyślna to 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 createPersistentCookie true createPersistentCookieis set to | A Boolean value that specifies whether the role cache cookie is a session cookie or persistent cookie. Iffalse(the default), a session cookie is used, which is deleted when the browser is closed. Iftrue, a persistent cookie is used; it expires . | | cookieTimeoutnumber of minutes after it has been created or after the previous visit, depending on the value ofcookieSlidingExpiration. 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. | | domainattribute, setting it to "yourdomain.com". | | | 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 themaxCachedResults | Specifies the maximum number of role names that are cached in the cookie. The default is 25. TheRoleManagerModuledoes 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 smallerwartość maxCachedResults; contrariwise, jeśli masz bardzo krótkie nazwy ról, prawdopodobnie można zwiększyć tę wartość. |

Tabela 1. Opcje konfiguracji plików cookie pamięci podręcznej roli

Skonfigurujmy aplikację tak, aby korzystała z plików cookie nietrwale pamięci podręcznej roli. W tym celu zaktualizuj <roleManager> element w Web.config pliku , aby uwzględnić następujące atrybuty związane z plikami cookie:

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

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

Zaktualizowałem element <roleManager>; dodając trzy atrybuty: cacheRolesInCookie, createPersistentCookiei cookieProtection. Ustawienie na cacheRolesInCookietruewartość spowoduje teraz RoleManagerModule automatyczne buforowanie ról użytkownika w pliku cookie zamiast wyszukiwania informacji o roli użytkownika w każdym żądaniu. Jawnie ustawiam createPersistentCookie atrybuty i cookieProtection odpowiednio na false i All. Technicznie, nie musiałem określać wartości dla tych atrybutów, ponieważ właśnie przypisuję je do ich wartości domyślnych, ale umieściłem je tutaj, aby wyraźnie wyjaśnić, że nie używam trwałych plików cookie i że plik cookie jest zarówno zaszyfrowany, jak i zweryfikowany.

To wszystko! W związku z tym platforma Role będzie buforować role użytkowników w plikach cookie. Jeśli przeglądarka użytkownika nie obsługuje plików cookie lub jeśli ich pliki cookie zostaną usunięte lub utracone, w jakiś sposób nie jest to wielka sprawa — RolePrincipal obiekt po prostu użyje Roles klasy w przypadku, gdy plik cookie (lub nieprawidłowy lub wygasły) jest dostępny.

Uwaga

Grupa Wzorce & rozwiązania firmy Microsoft zniechęca do używania trwałych plików cookie pamięci podręcznej ról. Ponieważ posiadanie pliku cookie pamięci podręcznej roli jest wystarczające do udowodnienia członkostwa w roli, jeśli haker może w jakiś sposób uzyskać dostęp do pliku cookie prawidłowego użytkownika, może personifikować tego użytkownika. Prawdopodobieństwo wystąpienia tego problemu zwiększa się, jeśli plik cookie jest utrwalany w przeglądarce użytkownika. Aby uzyskać więcej informacji na temat tego zalecenia dotyczącego zabezpieczeń, a także innych problemów z zabezpieczeniami, zapoznaj się z listą pytań dotyczących zabezpieczeń dla ASP.NET 2.0.

Krok 1. Definiowanie reguł autoryzacji adresu URL Role-Based

Zgodnie z opisem w samouczku autoryzacji opartej na użytkownikach autoryzacja adresów URL umożliwia ograniczenie dostępu do zestawu stron w oparciu o użytkownika lub rolę po rolach. Reguły autoryzacji adresu URL są pisane przy Web.config użyciu <authorization> elementu z elementami i <deny> elementami podrzędnymi<allow>. Oprócz reguł autoryzacji związanych z użytkownikiem omówionych w poprzednich samouczkach każdy <allow> element podrzędny <deny> może również obejmować:

  • Określona rola
  • Rozdzielana przecinkami lista ról

Na przykład reguły autoryzacji adresów URL udzielają dostępu do tych użytkowników w rolach Administratorzy i Nadzorcy, ale odmawiają dostępu wszystkim innym:

<authorization>

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

Element <allow> w powyższym znaczniku wskazuje, że role Administratorzy i Nadzorcy są dozwolone; <deny>element ; nakazuje wszystkim użytkownikom odmowę.

Skonfigurujmy naszą aplikację tak, aby ManageRoles.aspxstrony , UsersAndRoles.aspxi CreateUserWizardWithRoles.aspx były dostępne tylko dla tych użytkowników w roli Administratorzy, podczas gdy RoleBasedAuthorization.aspx strona pozostaje dostępna dla wszystkich odwiedzających.

Aby to osiągnąć, zacznij od dodania Web.config pliku do Roles folderu .

Dodawanie pliku Web.config do katalogu Roles

Rysunek 3. Dodawanie Web.config pliku do Roles katalogu (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Następnie dodaj następujący znacznik konfiguracji do :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>

Element <authorization> w <system.web> sekcji wskazuje, że tylko użytkownicy w roli Administratorzy mogą uzyskiwać dostęp do ASP.NET zasobów w Roles katalogu. Element <location> definiuje alternatywny zestaw reguł autoryzacji adresów URL dla RoleBasedAuthorization.aspx strony, umożliwiając wszystkim użytkownikom odwiedzanie strony.

Po zapisaniu zmian Web.configw programie zaloguj się jako użytkownik, który nie należy do roli Administratorzy, a następnie spróbuj odwiedzić jedną z chronionych stron. Program UrlAuthorizationModule wykryje, że nie masz uprawnień do odwiedzenia żądanego zasobu. W związku FormsAuthenticationModule z tym nastąpi przekierowanie do strony logowania. Następnie strona logowania przekierowuje Cię do UnauthorizedAccess.aspx strony (zobacz Rysunek 4). To ostatnie przekierowanie ze strony logowania ma UnauthorizedAccess.aspx miejsce z powodu kodu dodanego do strony logowania w kroku 2 samouczka autoryzacji opartej na użytkownikach. W szczególności strona logowania automatycznie przekierowuje uwierzytelnionego użytkownika do UnauthorizedAccess.aspx strony, jeśli ciąg zapytania zawiera ReturnUrl parametr, ponieważ ten parametr wskazuje, że użytkownik przybył na stronę logowania po próbie wyświetlenia strony, do którego nie został upoważniony do wyświetlania.

Tylko użytkownicy w roli Administratorzy mogą wyświetlać chronione strony

Rysunek 4. Tylko użytkownicy w roli Administratorzy mogą wyświetlać chronione strony (kliknij, aby wyświetlić obraz pełnowymiarowy)

Wyloguj się, a następnie zaloguj się jako użytkownik w roli Administratorzy. Teraz powinno być możliwe wyświetlenie trzech chronionych stron.

Tito może odwiedzić stronę UsersAndRoles.aspx, ponieważ jest on w roli administratorów

Rysunek 5. Tito może odwiedzić UsersAndRoles.aspx stronę, ponieważ jest on w roli administratorów (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Podczas określania reguł autoryzacji adresów URL — dla ról lub użytkowników — należy pamiętać, że reguły są analizowane pojedynczo od góry. Po znalezieniu dopasowania użytkownik otrzymuje lub odmawia dostępu, w zależności od tego, czy dopasowanie zostało znalezione w elemecie <allow> lub <deny> . Jeśli nie zostanie znalezione dopasowanie, użytkownik otrzyma dostęp. W związku z tym, jeśli chcesz ograniczyć dostęp do co najmniej jednego konta użytkownika, konieczne jest użycie elementu jako ostatniego <deny> elementu w konfiguracji autoryzacji adresu URL. Jeśli reguły autoryzacji adresu URL nie zawierają elementu<deny>— wszyscy użytkownicy otrzymają dostęp. Aby zapoznać się z bardziej szczegółowym omówieniem sposobu analizowania reguł autoryzacji adresów URL, zapoznaj się z sekcją "A Look at the Uses the UrlAuthorizationModule Authorization Rules to Grant or Deny Access" (Jak używać reguł autoryzacji do udzielania lub odmowy dostępu) w samouczku autoryzacji opartej na użytkownikach.

Krok 2. Ograniczanie funkcjonalności na podstawie aktualnie zalogowanych ról użytkownika

Autoryzacja adresu URL ułatwia określenie reguł autoryzacji grubszych, które określają, jakie tożsamości są dozwolone, i które z nich są odrzucane podczas wyświetlania określonej strony (lub wszystkich stron w folderze i jego podfolderach). Jednak w niektórych przypadkach możemy zezwolić wszystkim użytkownikom na odwiedzanie strony, ale ograniczyć funkcjonalność strony na podstawie ról użytkownika odwiedzającego. Może to wiązać się z wyświetlaniem lub ukrywaniem danych na podstawie roli użytkownika lub oferowanie dodatkowych funkcji użytkownikom należącym do określonej roli.

Takie szczegółowe reguły autoryzacji oparte na rolach można zaimplementować deklaratywnie lub programowo (lub za pomocą kombinacji tych dwóch). W następnej sekcji zobaczymy, jak zaimplementować autoryzację szczegółową deklaracyjną za pomocą kontrolki LoginView. Następnie zapoznamy się z technikami programowymi. Zanim jednak będziemy mogli przyjrzeć się zastosowaniu reguł autoryzacji szczegółowej, najpierw musimy utworzyć stronę, której funkcjonalność zależy od roli użytkownika odwiedzającego ją.

Utwórzmy stronę zawierającą listę wszystkich kont użytkowników w systemie w elementy GridView. Kontrolka GridView będzie zawierać nazwę użytkownika, adres e-mail, datę ostatniego logowania i komentarze dotyczące użytkownika. Oprócz wyświetlania informacji o każdym użytkowniku funkcja GridView będzie zawierać funkcje edytowania i usuwania. Początkowo utworzymy tę stronę z funkcją edycji i usuwania dostępną dla wszystkich użytkowników. W sekcjach "Korzystanie z kontrolki LoginView" i "Programowe ograniczanie funkcjonalności" zobaczymy, jak włączyć lub wyłączyć te funkcje na podstawie roli odwiedzającego użytkownika.

Uwaga

Strona ASP.NET, która zostanie skompilowane, używa kontrolki GridView do wyświetlania kont użytkowników. Ponieważ ta seria samouczków koncentruje się na uwierzytelnianiu formularzy, autoryzacji, kontach użytkowników i rolach, nie chcę poświęcać zbyt dużo czasu na omawianie wewnętrznych funkcji kontrolki GridView. Ten samouczek zawiera szczegółowe instrukcje krok po kroku dotyczące konfigurowania tej strony, ale nie zagłębia się w szczegóły, dlaczego zostały dokonane pewne wybory ani jaki wpływ mają określone właściwości na renderowane dane wyjściowe. Aby zapoznać się z dokładnym badaniem kontrolki GridView, zapoznaj się z serią samouczków Praca z danymi w ASP.NET 2.0 .

Zacznij od otwarcia RoleBasedAuthorization.aspx strony w folderze Roles . Przeciągnij obiekt GridView ze strony na Projektant i ustaw go ID na UserGridwartość . Za chwilę napiszemy kod, który wywołuje metodę Membership.GetAllUsers metoda i wiąże wynikowy MembershipUserCollection obiekt z obiektem GridView. Obiekt MembershipUserCollection zawiera MembershipUser obiekt dla każdego konta użytkownika w systemie; MembershipUser obiekty mają właściwości takie jak UserName,EmailLastLoginDate itd.

Zanim napiszemy kod, który wiąże konta użytkowników z siatką, najpierw zdefiniujmy pola obiektu GridView. W tagu inteligentnym gridView kliknij link "Edytuj kolumny", aby uruchomić okno dialogowe Pola (zobacz Rysunek 6). W tym miejscu usuń zaznaczenie pola wyboru "Automatycznie generuj pola" w lewym dolnym rogu. Ponieważ chcemy, aby ten obiekt GridView obejmował możliwości edytowania i usuwania, dodaj pole polecenia i ustaw jego ShowEditButtonShowDeleteButton właściwości na true. Następnie dodaj cztery pola do wyświetlania UserNamewłaściwości , Email, LastLoginDatei Comment . Użyj pola BoundField dla dwóch właściwości tylko do odczytu (UserName i ) i LastLoginDateTemplateFields dla dwóch pól edytowalnych (Email i Comment).

Aby pierwsze pole BoundField wyświetlało UserName właściwość , ustaw jej HeaderText właściwości i DataField na wartość "UserName". To pole nie będzie edytowalne, więc ustaw jego ReadOnly właściwość na True. Skonfiguruj pole LastLoginDate BoundField, ustawiając dla pola wartość HeaderText "Last Login" i na DataField wartość "LastLoginDate". Sformatujmy dane wyjściowe tego pola BoundField, aby wyświetlić tylko datę (zamiast daty i godziny). Aby to zrobić, ustaw dla właściwości BoundField HtmlEncode wartość False, a jej DataFormatString właściwość na wartość "{0:d}". Ustaw również właściwość na ReadOnly wartość True.

HeaderText Ustaw właściwości dwóch pól szablonów na "Email" i "Komentarz".

Pola kontrolki GridView można skonfigurować za pomocą okna dialogowego Pola

Rysunek 6. Pola kontrolki GridView można skonfigurować za pomocą okna dialogowego Pola (kliknij, aby wyświetlić obraz pełnowymiarowy)

Teraz musimy zdefiniować ItemTemplate elementy i EditItemTemplate dla pól szablonów "Email" i "Komentarz". Dodaj kontrolkę Sieć Web etykiet do każdego elementu ItemTemplates i powiąż ich Text właściwości odpowiednio z Email właściwościami i Comment .

W przypadku pola szablonu "Email" dodaj element TextBox o nazwie do Email jej EditItemTemplate właściwości i powiąż jego Text właściwość Email z właściwością przy użyciu dwukierunkowego powiązania danych. Dodaj element RequiredFieldValidator i RegularExpressionValidator do EditItemTemplate elementu , aby upewnić się, że odwiedzający edytujący właściwość Email wprowadził prawidłowy adres e-mail. W polu TemplateField "Komentarz" dodaj wielowierszową kontrolkę TextBox o nazwie Comment do elementu EditItemTemplate. Ustaw odpowiednio właściwości i Rows TextBox Columns na 40 i 4, a następnie powiąż jej Text właściwość z Comment właściwością przy użyciu dwukierunkowego powiązania danych.

Po skonfigurowaniu tych pól szablonów ich znaczniki deklaratywne powinny wyglądać podobnie do następujących:

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

Podczas edytowania lub usuwania konta użytkownika należy znać wartość właściwości tego użytkownika UserName . Ustaw właściwość GridView DataKeyNames na wartość "UserName", aby te informacje są dostępne za pośrednictwem kolekcji DataKeys GridView.

Na koniec dodaj kontrolkę ValidationSummary do strony i ustaw jej ShowMessageBox właściwość na True, a jej ShowSummary właściwość na False. Za pomocą tych ustawień funkcja ValidationSummary wyświetli alert po stronie klienta, jeśli użytkownik spróbuje edytować konto użytkownika z brakującym lub nieprawidłowym adresem e-mail.

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

Zakończyliśmy deklaratywne narzucie tej strony. Następnym zadaniem jest powiązanie zestawu kont użytkowników z kontrolką GridView. Dodaj metodę o nazwie BindUserGrid do RoleBasedAuthorization.aspx klasy code-behind strony, która wiąże element zwrócony MembershipUserCollection przez Membership.GetAllUsers z kontrolką UserGrid GridView. Wywołaj Page_Load tę metodę z programu obsługi zdarzeń na pierwszej stronie wizyty.

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

Po utworzeniu tego kodu odwiedź stronę za pośrednictwem przeglądarki. Jak pokazano na rysunku 7, w systemie powinien zostać wyświetlony widok GridView zawierający informacje o każdym koncie użytkownika.

Kontrolka UserGrid GridView wyświetla informacje o każdym użytkowniku w systemie

Rysunek 7. Kontrolka UserGrid GridView wyświetla informacje o każdym użytkowniku w systemie (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Uwaga

Kontrolka UserGrid GridView wyświetla listę wszystkich użytkowników w interfejsie niestronicowanym. Ten prosty interfejs siatki nie jest odpowiedni w scenariuszach, w których istnieje kilkadziesiąt lub więcej użytkowników. Jedną z opcji jest skonfigurowanie kontrolki GridView w celu włączenia stronicowania. Metoda Membership.GetAllUsers ma dwa przeciążenia: jeden, który nie akceptuje parametrów wejściowych i zwraca wszystkich użytkowników i jeden, który przyjmuje wartości całkowite dla indeksu strony i rozmiar strony, i zwraca tylko określony podzestaw użytkowników. Drugie przeciążenie może służyć do wydajniejszej strony za pośrednictwem użytkowników, ponieważ zwraca tylko dokładny podzbiór kont użytkowników, a nie wszystkich z nich. Jeśli masz tysiące kont użytkowników, warto rozważyć interfejs oparty na filtrze, który pokazuje tylko tych użytkowników, których nazwa użytkownika zaczyna się od wybranego znaku, na przykład. Metoda jest idealna Membership.FindUsersByName do tworzenia interfejsu użytkownika opartego na filtrach. W przyszłym samouczku przyjrzymy się tworzeniu takiego interfejsu.

Kontrolka GridView oferuje wbudowaną obsługę edytowania i usuwania, gdy kontrolka jest powiązana z prawidłowo skonfigurowaną kontrolką źródła danych, taką jak SqlDataSource lub ObjectDataSource. Obiekt UserGrid GridView ma jednak dane powiązane programowo, dlatego musimy napisać kod, aby wykonać te dwa zadania. W szczególności należy utworzyć programy obsługi zdarzeń dla zdarzeń, , RowCancelingEditRowUpdatingi RowDeleting zdarzeń GridViewRowEditing, które są uruchamiane po kliknięciu przycisków Edytuj, Anuluj, Aktualizuj lub Usuń obiektu GridView.

Zacznij od utworzenia programów obsługi zdarzeń dla zdarzeń , RowCancelingEditi RowUpdating zdarzeń gridViewRowEditing, a następnie dodaj następujący kod:

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

Programy RowEditing obsługi zdarzeń i RowCancelingEdit po prostu ustawić właściwość GridView EditIndex , a następnie ponownie połączyć listę kont użytkowników z siatką. Interesujące rzeczy są wykonywane w procedurze obsługi zdarzeń RowUpdating . Ta procedura obsługi zdarzeń rozpoczyna się od upewnienia się, że dane są prawidłowe, a następnie pobiera UserName wartość edytowanego konta użytkownika z kolekcji DataKeys . Pola Email tekstowe i Comment w tych dwóch polach TemplateFields EditItemTemplate są następnie programowo przywołyne. Ich Text właściwości zawierają edytowany adres e-mail i komentarz.

Aby zaktualizować konto użytkownika za pomocą interfejsu API członkostwa, musimy najpierw uzyskać informacje o użytkowniku, które wykonujemy za pośrednictwem wywołania metody Membership.GetUser(userName). Zwrócony MembershipUserEmail obiekt i Comment właściwości są następnie aktualizowane przy użyciu wartości wprowadzonych do dwóch pól TextBoxes z interfejsu edycji. Na koniec te modyfikacje są zapisywane za pomocą wywołania metody Membership.UpdateUser. Procedura RowUpdating obsługi zdarzeń zostanie ukończona przez przywrócenie obiektu GridView do interfejsu wstępnego edytowania.

Następnie utwórz procedurę RowDeleting obsługi zdarzeń RowDeleting, a następnie dodaj następujący kod:

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

Powyższy program obsługi zdarzeń rozpoczyna się od pobrania UserName wartości z kolekcji GridView DataKeys . Ta UserName wartość jest następnie przekazywana DeleteUser do metody klasy Membership. Metoda DeleteUser usuwa konto użytkownika z systemu, w tym powiązane dane członkostwa (takie jak role, do których należy ten użytkownik). Po usunięciu użytkownika siatka EditIndex jest ustawiona na -1 (jeśli użytkownik kliknął przycisk Usuń, gdy inny wiersz był w trybie edycji), a BindUserGrid metoda jest wywoływana.

Uwaga

Przycisk Usuń nie wymaga żadnego potwierdzenia od użytkownika przed usunięciem konta użytkownika. Zachęcam do dodania jakiejś formy potwierdzenia użytkownika, aby zmniejszyć prawdopodobieństwo przypadkowego usunięcia konta. Jednym z najprostszych sposobów potwierdzenia akcji jest okno dialogowe potwierdzania po stronie klienta. Aby uzyskać więcej informacji na temat tej techniki, zobacz Dodawanie potwierdzenia Client-Side podczas usuwania.

Sprawdź, czy ta strona działa zgodnie z oczekiwaniami. Należy mieć możliwość edytowania adresu e-mail i komentarza użytkownika, a także usuwania dowolnego konta użytkownika. RoleBasedAuthorization.aspx Ponieważ strona jest dostępna dla wszystkich użytkowników, każdy użytkownik — nawet anonimowy odwiedzający — może odwiedzać tę stronę i edytować i usuwać konta użytkowników. Zaktualizujmy tę stronę, aby tylko użytkownicy w rolach Nadzorcy i Administratorzy mogli edytować adres e-mail i komentarz użytkownika, a tylko administratorzy mogą usunąć konto użytkownika.

Sekcja "Korzystanie z kontrolki LoginView" dotyczy używania kontrolki LoginView w celu wyświetlenia instrukcji specyficznych dla roli użytkownika. Jeśli osoba w roli Administratorzy odwiedza tę stronę, pokażemy instrukcje dotyczące edytowania i usuwania użytkowników. Jeśli użytkownik w roli Nadzorcy osiągnie tę stronę, pokażemy instrukcje dotyczące edytowania użytkowników. Jeśli gość jest anonimowy lub nie znajduje się w roli Nadzorcy lub Administratorzy, zostanie wyświetlony komunikat wyjaśniający, że nie może edytować ani usuwać informacji o koncie użytkownika. W sekcji "Programowe ograniczanie funkcjonalności" napiszemy kod, który programowo pokazuje lub ukrywa przyciski Edytuj i Usuń na podstawie roli użytkownika.

Korzystanie z kontrolki LoginView

Jak widzieliśmy w poprzednich samouczkach, kontrolka LoginView jest przydatna do wyświetlania różnych interfejsów dla uwierzytelnionych i anonimowych użytkowników, ale kontrolka LoginView może również służyć do wyświetlania różnych znaczników na podstawie ról użytkownika. Użyjmy kontrolki LoginView, aby wyświetlić różne instrukcje na podstawie roli użytkownika odwiedzającego.

Zacznij od dodania kontrolki LoginView powyżej kontrolki UserGrid GridView. Jak wspomniano wcześniej, kontrolka LoginView ma dwa wbudowane szablony: AnonymousTemplate i LoggedInTemplate. Wprowadź krótki komunikat w obu tych szablonach, który informuje użytkownika, że nie może edytować ani usuwać żadnych informacji o użytkowniku.

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

Oprócz kontrolek AnonymousTemplate i LoggedInTemplatekontrolka LoginView może zawierać grupy ról, które są szablonami specyficznymi dla ról. Każda grupa ról zawiera jedną właściwość , która określa, Rolesdo jakich ról ma zastosowanie grupa ról. Właściwość Roles można ustawić na jedną rolę (na przykład "Administratorzy") lub rozdzielać przecinkami listę ról (na przykład "Administratorzy, Nadzorcy").

Aby zarządzać grupami ról, kliknij link "Edytuj grupy ról" z tagu inteligentnego kontrolki, aby wyświetlić Edytor kolekcji RoleGroup. Dodaj dwie nowe grupy ról. Ustaw właściwość pierwszej grupy ról Roles na "Administratorzy", a druga na "Nadzorcy".

Zarządzanie szablonami Role-Specific elementu LoginView za pomocą edytora kolekcji RoleGroup

Rysunek 8. Zarządzanie szablonami Role-Specific elementu LoginView za pomocą Edytora kolekcji RoleGroup (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Kliknij przycisk OK, aby zamknąć Edytor kolekcji RoleGroup; Spowoduje to zaktualizowanie deklaratywnego narzutu kontrolki LoginView w celu uwzględnienia <RoleGroups> sekcji z elementem podrzędnym <asp:RoleGroup> dla każdej grupy ról zdefiniowanej w Edytorze kolekcji RoleGroup. Ponadto lista rozwijana "Widoki" na liście inteligentnej elementu LoginView — która początkowo zawierała tylko AnonymousTemplate wartości i LoggedInTemplate — zawiera również dodane grupy ról.

Edytuj grupy ról, aby użytkownicy w roli Nadzorcy wyświetlali instrukcje dotyczące edytowania kont użytkowników, a użytkownicy w roli Administratorzy są wyświetlane instrukcje dotyczące edytowania i usuwania. Po wprowadzeniu tych zmian znacznik deklaratywny elementu LoginView powinien wyglądać podobnie do poniższego.

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

Po wprowadzeniu tych zmian zapisz stronę, a następnie przejdź do niej za pośrednictwem przeglądarki. Najpierw odwiedź stronę jako użytkownik anonimowy. Powinien zostać wyświetlony komunikat "Nie logujesz się do systemu. W związku z tym nie można edytować ani usuwać żadnych informacji o użytkowniku". Następnie zaloguj się jako uwierzytelniony użytkownik, ale taki, który nie należy ani do roli Nadzorców, ani Administratorów. Tym razem powinien zostać wyświetlony komunikat "Nie jesteś członkiem ról nadzorców ani administratorów. W związku z tym nie można edytować ani usuwać żadnych informacji o użytkowniku".

Następnie zaloguj się jako użytkownik będący członkiem roli Nadzorcy. Tym razem powinien zostać wyświetlony komunikat specyficzny dla ról nadzorców (zobacz Rysunek 9). Jeśli logujesz się jako użytkownik w roli Administratorzy, powinien zostać wyświetlony komunikat Administratorzy specyficzny dla roli (zobacz Rysunek 10).

Bruce jest pokazany nadzorcy Role-Specific wiadomość

Rysunek 9. Bruce jest wyświetlany nadzorcy Role-Specific komunikat (kliknij, aby wyświetlić obraz pełnowymiarowy)

Tito jest wyświetlane administratorzy Role-Specific komunikat

Rysunek 10. Tito jest wyświetlany administratorom Role-Specific komunikat (kliknij, aby wyświetlić obraz pełnowymiarowy)

Jak pokazano na zrzutach ekranu na rysunkach 9 i 10, kontrolka LoginView renderuje tylko jeden szablon, nawet jeśli zastosowano wiele szablonów. Bruce i Tito są zalogowanymi użytkownikami, ale element LoginView renderuje tylko pasującą grupę LoggedInTemplateRoleGroup, a nie . Ponadto Tito należy zarówno do ról Administratorzy, jak i Nadzorcy, ale kontrolka LoginView renderuje szablon specyficzny dla roli Administratorzy zamiast nadzorców.

Rysunek 11 przedstawia przepływ pracy używany przez kontrolkę LoginView w celu określenia szablonu do renderowania. Należy pamiętać, że jeśli określono więcej niż jedną grupę ról, szablon LoginView renderuje pierwszą grupę ról zgodną z tym elementem. Innymi słowy, gdybyśmy umieścili nadzorców RoleGroup jako pierwszą grupę RoleGroup i administratorów jako drugą, to kiedy Tito odwiedził tę stronę, zobaczy komunikat Nadzorcy.

Przepływ pracy kontrolki LoginView na potrzeby określania szablonu do renderowania

Rysunek 11. Przepływ pracy kontrolki LoginView do określania szablonu do renderowania (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Programowe ograniczanie funkcjonalności

Kontrolka LoginView wyświetla różne instrukcje na podstawie roli użytkownika odwiedzającego stronę, ale przyciski Edytuj i Anuluj pozostają widoczne dla wszystkich. Musimy programowo ukryć przyciski Edytuj i Usuń dla anonimowych osób odwiedzających i użytkowników, którzy nie mają roli Nadzorcy ani Administratorzy. Musimy ukryć przycisk Usuń dla wszystkich, którzy nie są administratorami. W celu osiągnięcia tego celu napiszemy trochę kodu, który programowo odwołuje się do poleceń CommandField's Edit and Delete LinkButtons i ustawia ich Visible właściwości na False, jeśli to konieczne.

Najprostszym sposobem programowego odwoływanie się do kontrolek w pole polecenia jest najpierw przekonwertowanie jej na szablon. Aby to osiągnąć, kliknij link "Edytuj kolumny" z tagu inteligentnego kontrolki GridView, wybierz pole polecenia z listy bieżących pól, a następnie kliknij link "Konwertuj to pole na pole szablonu". Spowoduje to zmianę pola commandfield w pole szablonu z elementami i ItemTemplateEditItemTemplate. Zawiera ItemTemplate elementy Edit and Delete LinkButtons, a EditItemTemplate obiekt zawiera kontrolkę Update i Cancel LinkButtons.

Konwertowanie pola polecenia na pole szablonu

Rysunek 12. Konwertowanie pola polecenia na pole szablonu (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Zaktualizuj kontrolkę Edit and Delete LinkButtons w obiekcie ItemTemplate, ustawiając ich ID właściwości odpowiednio na wartości EditButton i DeleteButton.

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

Za każdym razem, gdy dane są powiązane z obiektem GridView, funkcja GridView wylicza rekordy we właściwości DataSource i generuje odpowiedni GridViewRow obiekt. Po utworzeniu RowCreated każdego GridViewRow obiektu zdarzenie jest wyzwalane. Aby ukryć przyciski Edytuj i Usuń dla nieautoryzowanych użytkowników, musimy utworzyć procedurę obsługi zdarzeń dla tego zdarzenia i programowo odwołać się do przycisków Edytuj i Usuń LinkButton, ustawiając odpowiednie Visible właściwości.

Utwórz procedurę obsługi zdarzeń, RowCreated a następnie dodaj następujący kod:

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

Należy pamiętać, że RowCreated zdarzenie jest wyzwalane dla wszystkich wierszy kontrolki GridView, w tym nagłówka, stopki, interfejsu pagera itd. Chcemy programowo odwołać się tylko do przycisków Edytuj i Usuń, jeśli mamy do czynienia z wierszem danych, który nie jest w trybie edycji (ponieważ wiersz w trybie edycji ma przyciski Aktualizuj i Anuluj zamiast Edytuj i Usuń). To sprawdzenie jest obsługiwane przez instrukcję If .

Jeśli mamy do czynienia z wierszem danych, który nie jest w trybie edycji, odwołania do elementów Edit i Delete LinkButton są przywoływane, a ich Visible właściwości są ustawiane na podstawie wartości logicznych zwracanych przez User metodę obiektu IsInRole(roleName) . Obiekt User odwołuje się do podmiotu zabezpieczeń utworzonego RoleManagerModuleprzez element ; w związku z tym metoda używa interfejsu API ról do określenia, IsInRole(roleName) czy bieżący gość należy do roleName.

Uwaga

Moglibyśmy bezpośrednio użyć klasy Roles, zastępując wywołanie metody User.IsInRole(roleName) wywołaniem Roles.IsUserInRole(roleName) metody . Postanowiłem użyć metody obiektu IsInRole(roleName) głównego w tym przykładzie, ponieważ jest ona wydajniejsza niż bezpośrednie użycie interfejsu API ról. Wcześniej w tym samouczku skonfigurowaliśmy menedżera ról do buforowania ról użytkownika w pliku cookie. Te buforowane dane plików cookie są używane tylko wtedy, gdy jest wywoływana IsInRole(roleName) metoda podmiotu zabezpieczeń. Bezpośrednie wywołania interfejsu API ról zawsze obejmują podróż do magazynu ról. Nawet jeśli role nie są buforowane w pliku cookie, wywoływanie metody obiektu IsInRole(roleName) głównego jest zwykle bardziej wydajne, ponieważ gdy jest wywoływana po raz pierwszy podczas żądania, buforuje wyniki. Z drugiej strony interfejs API ról nie wykonuje buforowania. RowCreated Ponieważ zdarzenie jest uruchamiane raz dla każdego wiersza w siatce, użycie obejmuje User.IsInRole(roleName) tylko jedną podróż do magazynu ról, podczas gdy Roles.IsUserInRole(roleName) wymaga N podróży, gdzie N jest liczbą kont użytkowników wyświetlanych w siatce.

Właściwość przycisku Edytuj jest ustawiona Visible na True wartość , jeśli użytkownik odwiedzający tę stronę znajduje się w roli Administratorzy lub Nadzorcy. W przeciwnym razie jest ustawiona wartość False. Właściwość przycisku Usuń jest ustawiona Visible na wartość tylko wtedy, gdy użytkownik należy do True roli Administratorzy.

Przetestuj tę stronę za pomocą przeglądarki. Jeśli odwiedzasz stronę jako anonimowy gość lub jako użytkownik, który nie jest nadzorcą ani administratorem, pole CommandField jest puste; nadal istnieje, ale jako cienki odcięcie bez przycisków Edytuj lub Usuń.

Uwaga

Istnieje możliwość całkowitego ukrycia pola CommandField, gdy strona jest odwiedzana przez użytkownika niebędącego nadzorcą i nieadministratorem. Zostawię to jako ćwiczenie dla czytelnika.

Przyciski Edytuj i Usuń są ukryte dla osób niebędących nadzorcami i nieadministratorów

Rysunek 13. Przyciski Edytowania i usuwania są ukryte dla osób niebędących nadzorcami i nieadministratorów (kliknij, aby wyświetlić obraz pełnowymiarowy)

Jeśli użytkownik należący do roli Nadzorców (ale nie do roli Administratorzy) odwiedza tylko przycisk Edytuj.

Gdy przycisk Edytuj jest dostępny dla nadzorców, przycisk Usuń jest ukryty

Rysunek 14. Gdy przycisk Edytuj jest dostępny dla nadzorców, przycisk Usuń jest ukryty (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Jeśli administrator odwiedzi, ma dostęp zarówno do przycisków Edytuj, jak i Usuń.

Przyciski Edytuj i Usuń są dostępne tylko dla administratorów

Rysunek 15. Przyciski edycji i usuwania są dostępne tylko dla administratorów (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Krok 3. Stosowanie reguł autoryzacji Role-Based do klas i metod

W kroku 2 ograniczamy możliwości edytowania użytkowników w rolach Nadzorców i Administratorów oraz usuwamy możliwości tylko administratorom. Można to osiągnąć, ukrywając skojarzone elementy interfejsu użytkownika dla nieautoryzowanych użytkowników za pomocą technik programistycznych. Takie środki nie gwarantują, że nieautoryzowany użytkownik nie będzie mógł wykonać akcji uprzywilejowanej. Mogą istnieć elementy interfejsu użytkownika, które zostały dodane później lub że zapomnieliśmy ukryć się dla nieautoryzowanych użytkowników. Lub haker może odkryć inny sposób, aby uzyskać stronę ASP.NET w celu wykonania żądanej metody.

Łatwym sposobem zapewnienia dostępu do określonego elementu funkcjonalności przez nieautoryzowanego użytkownika jest dekorowanie tej klasy lub metody za pomocą atrybutuPrincipalPermission . Gdy środowisko uruchomieniowe platformy .NET używa klasy lub wykonuje jedną z jej metod, sprawdza, czy bieżący kontekst zabezpieczeń ma uprawnienia. Atrybut PrincipalPermission udostępnia mechanizm, za pomocą którego można zdefiniować te reguły.

Przyjrzeliśmy się używaniu atrybutu PrincipalPermission z powrotem w samouczku autoryzacji opartej na użytkownikach. W szczególności zobaczyliśmy, jak ozdobić program obsługi zdarzeń i RowDeleting GridViewSelectedIndexChanged, aby mogły być wykonywane tylko przez uwierzytelnionych użytkowników i Tito, odpowiednio. Atrybut PrincipalPermission działa równie dobrze z rolami.

Pokażmy, jak używać atrybutu PrincipalPermission w programach obsługi zdarzeń i RowDeleting gridviewRowUpdating, aby uniemożliwić wykonywanie nieautoryzowanych użytkowników. Wszystko, co musimy zrobić, to dodać odpowiedni atrybut na szczycie każdej definicji funkcji:

<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

Atrybut programu RowUpdating obsługi zdarzeń określa, że tylko użytkownicy w rolach Administratorzy lub Nadzorcy mogą wykonywać program obsługi zdarzeń, gdzie jako atrybut RowDeleting programu obsługi zdarzeń ogranicza wykonywanie do użytkowników w roli Administratorzy.

Uwaga

Atrybut PrincipalPermission jest reprezentowany jako klasa w System.Security.Permissions przestrzeni nazw. Pamiętaj, aby dodać instrukcję Imports System.Security.Permissions w górnej części pliku klasy za kodem, aby zaimportować tę przestrzeń nazw.

Jeśli w jakiś sposób nieadministrator próbuje wykonać procedurę RowDeleting obsługi zdarzeń lub jeśli inny niż nadzorca lub inny niż administrator spróbuje wykonać RowUpdating procedurę obsługi zdarzeń, środowisko uruchomieniowe platformy .NET zgłosi błąd SecurityException.

Jeśli kontekst zabezpieczeń nie ma autoryzacji do wykonania metody, zgłaszany jest wyjątek SecurityException

Rysunek 16. Jeśli kontekst zabezpieczeń nie ma autoryzacji do wykonania metody, SecurityException jest zgłaszany (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Oprócz stron ASP.NET wiele aplikacji ma również architekturę obejmującą różne warstwy, takie jak logika biznesowa i warstwy dostępu do danych. Te warstwy są zwykle implementowane jako biblioteki klas i oferują klasy i metody do wykonywania funkcji związanych z logiką biznesową i danymi. Atrybut PrincipalPermission przydaje się również do stosowania reguł autoryzacji do tych warstw.

Aby uzyskać więcej informacji na temat używania atrybutu PrincipalPermission do definiowania reguł autoryzacji dla klas i metod, zapoznaj się z wpisem w blogu Scotta GuthrieDodawanie reguł autoryzacji do warstw biznesowych i danych przy użyciu polecenia PrincipalPermissionAttributes.

Podsumowanie

W tym samouczku przyjrzeliśmy się sposobom określania reguł autoryzacji gruboziarnistej i szczegółowej na podstawie ról użytkownika. ASP. Funkcja autoryzacji adresów URL platformy NET umożliwia deweloperowi strony określenie, jakie tożsamości są dozwolone lub odmawiane dostępu do jakich stron. Jak już widzieliśmy w samouczku autoryzacji opartej na użytkownikach, reguły autoryzacji adresów URL można stosować dla poszczególnych użytkowników. Można je również stosować w oparciu o rolę, jak pokazano w kroku 1 tego samouczka.

Reguły autoryzacji szczegółowej mogą być stosowane deklaratywnie lub programowo. W kroku 2 przyjrzeliśmy się używaniu funkcji RoleGroups kontrolki LoginView do renderowania różnych danych wyjściowych na podstawie ról użytkownika odwiedzającego. Przyjrzeliśmy się również sposobom programowego określania, czy użytkownik należy do określonej roli i jak odpowiednio dostosować funkcjonalność strony.

Szczęśliwe programowanie!

Dalsze informacje

Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:

Informacje o autorze

Scott Mitchell, autor wielu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Scott można dotrzeć pod mitchell@4guysfromrolla.com adresem lub za pośrednictwem swojego bloga pod adresem http://ScottOnWriting.NET.

Specjalne podziękowania...

Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Recenzenci z tego samouczka to Suchi Banerjee i Teresa Murphy. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi linię na mitchell@4GuysFromRolla.com