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.config
moż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.
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)
Buforowanie informacji o roli w pliku cookie
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 SqlRoleProvider
programu powoduje to wysłanie zapytania do bazy danych magazynu ról. W przypadku korzystania z reguł RolePrincipal
autoryzacji 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 EndRequest
ASP.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.
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 to
true. | |
cookieTimeout | Specifies the time, in minutes, after which the authentication ticket cookie expires. The default value is
30. 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. If
false(the default), a session cookie is used, which is deleted when the browser is closed. If
true, a persistent cookie is used; it expires
. | |
cookieTimeoutnumber of minutes after it has been created or after the previous visit, depending on the value of
cookieSlidingExpiration. 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 the
maxCachedResults | Specifies the maximum number of role names that are cached in the cookie. The default is 25. The
RoleManagerModuledoes not create a cookie for users that belong to more than
maxCachedResultsroles. Consequently, the
RolePrincipalobject's
IsInRolemethod will use the
Rolesclass to determine the user's roles. The reason
maxCachedResultsexists 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
wartość 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
, createPersistentCookie
i cookieProtection
. Ustawienie na cacheRolesInCookie
true
wartość 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.aspx
strony , UsersAndRoles.aspx
i 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 .
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.config
w 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.
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.
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 UserGrid
wartość . 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
,Email
LastLoginDate
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 ShowEditButton
ShowDeleteButton
właściwości na true. Następnie dodaj cztery pola do wyświetlania UserName
właściwości , Email
, LastLoginDate
i Comment
. Użyj pola BoundField dla dwóch właściwości tylko do odczytu (UserName
i ) i LastLoginDate
TemplateFields 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".
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.
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ń, , RowCancelingEdit
RowUpdating
i 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ń , RowCancelingEdit
i 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 MembershipUser
Email
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 LoggedInTemplate
kontrolka 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, Roles
do 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".
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' 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).
Rysunek 9. Bruce jest wyświetlany nadzorcy Role-Specific komunikat (kliknij, aby wyświetlić obraz pełnowymiarowy)
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ę LoggedInTemplate
RoleGroup, 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.
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 ItemTemplate
EditItemTemplate
. Zawiera ItemTemplate
elementy Edit and Delete LinkButtons, a EditItemTemplate
obiekt zawiera kontrolkę Update i Cancel LinkButtons.
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 RoleManagerModule
przez 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.
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.
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ń.
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
.
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:
- Dodawanie reguł autoryzacji do warstw biznesowych i danych przy użyciu polecenia
PrincipalPermissionAttributes
- Badanie członkostwa, ról i profilu ASP.NET 2.0: Praca z rolami
- Lista pytań dotyczących zabezpieczeń dla ASP.NET 2.0
- Dokumentacja techniczna elementu
<roleManager>
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