Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Autor : Scott Mitchell
Uwaga / Notatka
Od czasu napisania tego artykułu dostawcy członkostwa ASP.NET zostały zastąpione przez ASP.NET Identity. Zdecydowanie zalecamy aktualizowanie aplikacji w celu korzystania z platformy ASP.NET Identity , a nie dostawców członkostwa proponowanych w czasie pisania tego artykułu. ASP.NET Identity ma wiele zalet w stosunku do systemu 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 identyfikacji opartej na żądaniach
- Lepsza współdziałanie z platformą ASP.Net Core
Pobierz kod lub pobierz plik PDF
W tym samouczku przejdziemy od samej dyskusji do implementacji; w szczególności przyjrzymy się implementowaniu uwierzytelniania formularzy. Aplikacja internetowa, którą zaczynamy budować w tym samouczku, będzie rozwijana w kolejnych samouczkach, gdy przechodzimy od prostego uwierzytelniania formularzy do członkostwa i ról.
Zobacz ten film, aby uzyskać więcej informacji na ten temat: Podstawowe uwierzytelnianie formularzy w ASP.NET.
Wprowadzenie
W poprzednim samouczku omówiliśmy różne opcje uwierzytelniania, autoryzacji i konta użytkownika udostępniane przez ASP.NET. W tym samouczku przejdziemy od samej dyskusji do implementacji; w szczególności przyjrzymy się implementowaniu uwierzytelniania formularzy. Aplikacja internetowa, którą zaczynamy budować w tym samouczku, będzie rozwijana w kolejnych samouczkach, gdy przechodzimy od prostego uwierzytelniania formularzy do członkostwa i ról.
Ten samouczek rozpoczyna się od szczegółowego przyjrzenia się przepływowi pracy uwierzytelniania formularzy— tematu, który omówiliśmy w poprzednim samouczku. Następnie utworzymy witrynę internetową ASP.NET, za pomocą której przedstawimy koncepcje uwierzytelniania formularzy. Następnie skonfigurujemy witrynę do korzystania z uwierzytelniania formularzy, utworzymy prostą stronę logowania i zobaczymy, jak określić, w kodzie, czy użytkownik jest uwierzytelniony, a jeśli tak, nazwa użytkownika, za pomocą której się zalogował.
Zrozumienie przepływu pracy uwierzytelniania formularzy, włączenie go w aplikacji internetowej i utworzenie stron logowania i wylogowania są istotnymi krokami tworzenia aplikacji ASP.NET, która obsługuje konta użytkowników i uwierzytelnia użytkowników za pośrednictwem strony internetowej. W związku z tym — i dlatego, że te samouczki opierają się na sobie nawzajem — zachęcam do pracy z tym samouczkiem w całości przed przejściem do następnego, nawet jeśli masz już doświadczenie w konfigurowaniu uwierzytelniania formularzy w poprzednich projektach.
Opis przepływu pracy uwierzytelniania formularzy
Gdy środowisko uruchomieniowe ASP.NET przetwarza żądanie zasobu ASP.NET, takiego jak strona ASP.NET lub usługa sieci Web ASP.NET, żądanie zgłasza wiele zdarzeń podczas cyklu życia. Istnieją zdarzenia zgłaszane na samym początku i na samym końcu żądania, które są zgłaszane, gdy żądanie jest uwierzytelniane i autoryzowane, zdarzenie zgłoszone w przypadku nieobsługiwanego wyjątku itd. Aby wyświetlić pełną listę zdarzeń, zapoznaj się ze zdarzeniami obiektu HttpApplication.
Moduły HTTP to klasy zarządzane, których kod jest wykonywany w odpowiedzi na określone zdarzenie w cyklu życia żądania. ASP.NET zawiera wiele modułów HTTP, które wykonują niezbędne zadania w tle. Dwa wbudowane moduły HTTP, które są szczególnie istotne dla naszej dyskusji, to:
-
FormsAuthenticationModule— uwierzytelnia użytkownika, sprawdzając bilet uwierzytelniania formularzy, który jest zwykle zawarty w kolekcji plików cookie użytkownika. Jeśli nie ma biletu uwierzytelniania formularzy, użytkownik jest anonimowy. -
UrlAuthorizationModule— określa, czy bieżący użytkownik ma uprawnienia dostępu do żądanego adresu URL. Ten moduł określa autorytet, przez konsultację z regułami autoryzacji określonymi w plikach konfiguracyjnych aplikacji. ASP.NET zawiera także funkcję, która określa uprawnienia, konsultując listy kontroli dostępu (ACL) żądanych plików.
FormsAuthenticationModule próby uwierzytelnienia użytkownika przed wykonaniem UrlAuthorizationModule (i FileAuthorizationModule). Jeśli użytkownik wysyłający żądanie nie ma autoryzacji dostępu do żądanego zasobu, moduł autoryzacji kończy żądanie i zwraca stan HTTP 401 Brak autoryzacji . W scenariuszach uwierzytelniania systemu Windows stan HTTP 401 jest zwracany do przeglądarki. Ten kod stanu powoduje, że przeglądarka wyświetli monit o podanie poświadczeń użytkownika za pośrednictwem modalnego okna dialogowego. Jednak w przypadku uwierzytelniania formularzy stan HTTP 401 Brak autoryzacji nigdy nie jest wysyłany do przeglądarki, ponieważ moduł FormsAuthenticationModule wykrywa ten stan i modyfikuje go w celu przekierowania użytkownika do strony logowania (za pośrednictwem stanu przekierowania HTTP 302 ).
Obowiązkiem strony logowania jest określenie, czy poświadczenia użytkownika są prawidłowe, a jeśli tak, aby utworzyć bilet uwierzytelniania formularzy i przekierować użytkownika z powrotem do strony, którą próbowali odwiedzić. Bilet uwierzytelniania jest uwzględniany w kolejnych żądaniach do stron w witrynie internetowej, których FormsAuthenticationModule używa do identyfikowania użytkownika.
Rysunek 1. Przepływ pracy uwierzytelniania formularzy
Pamiętanie biletu uwierzytelniania między wizytami na stronie
Po zalogowaniu się bilet uwierzytelniania formularzy musi zostać odesłany do serwera internetowego na każdym żądaniu, aby użytkownik pozostał zalogowany podczas przeglądania witryny. Zazwyczaj jest to realizowane przez umieszczenie biletu uwierzytelniania w kolekcji plików cookie użytkownika. Pliki cookie to małe pliki tekstowe, które znajdują się na komputerze użytkownika i są przesyłane w nagłówkach HTTP w każdym żądaniu do witryny internetowej, która utworzyła plik cookie. W związku z tym po utworzeniu i zapisaniu biletu uwierzytelniania formularzy w plikach cookie przeglądarki każda kolejna wizyta w tej witrynie wysyła bilet uwierzytelniania wraz z żądaniem, identyfikując w ten sposób użytkownika.
Jednym z aspektów plików cookie jest ich wygaśnięcie, czyli data i godzina odrzucenia pliku cookie przez przeglądarkę. Po wygaśnięciu pliku cookie uwierzytelniania formularzy użytkownik nie może być już uwierzytelniany i w związku z tym staje się anonimowy. Kiedy użytkownik odwiedza stronę z publicznego terminala, istnieje duża szansa, że będzie chciał, aby jego bilet uwierzytelniania wygasł po zamknięciu przeglądarki. Podczas wizyty z domu ten sam użytkownik może chcieć, aby token uwierzytelniania był zapamiętany podczas restartów przeglądarki, aby nie musiał ponownie logować się za każdym razem, gdy odwiedza witrynę. Ta decyzja jest często podjęta przez użytkownika w postaci pola wyboru "Zapamiętaj mnie" na stronie logowania. W kroku 3 sprawdzimy, jak zaimplementować pole wyboru "Zapamiętaj mnie" na stronie logowania. W poniższym samouczku szczegółowo opisano ustawienia limitu czasu tokenu uwierzytelniania.
Uwaga / Notatka
Możliwe, że agent użytkownika używany do logowania się do witryny internetowej może nie obsługiwać plików cookie. W takim przypadku ASP.NET może używać uwierzytelniania formularzy bez użycia plików cookie. W tym trybie bilet uwierzytelniania jest zakodowany w adresie URL. Przyjrzymy się, kiedy są używane tokeny uwierzytelniania niewymagające plików cookie oraz jak są tworzone i zarządzane w następnym samouczku.
Zakres uwierzytelniania formularzy
FormsAuthenticationModule to kod zarządzany, będący częścią środowiska uruchomieniowego ASP.NET. Przed wersją 7 serwera internetowego usług Internet Information Services (IIS) firmy Microsoft istniała odrębna bariera między potokiem HTTP usług IIS a potokiem ASP.NET środowiska uruchomieniowego. Krótko mówiąc, w usługach IIS 6 i starszych FormsAuthenticationModule wykonuje się tylko wtedy, gdy żądanie jest delegowane z usług IIS do środowiska uruchomieniowego ASP.NET. Domyślnie usługi IIS przetwarza samą zawartość statyczną — na przykład strony HTML i pliki CSS i obrazy — i wysyłają żądania do środowiska uruchomieniowego ASP.NET tylko wtedy, gdy żądana jest strona z rozszerzeniem .aspx, asmx lub ashx.
IIS 7 jednak umożliwia zintegrowane potoki IIS i ASP.NET. Za pomocą kilku ustawień konfiguracji można skonfigurować usługi IIS 7 w celu wywołania modułu FormsAuthenticationModule dla wszystkich żądań. Ponadto za pomocą usług IIS 7 można zdefiniować reguły autoryzacji adresów URL dla plików dowolnego typu. Aby uzyskać więcej informacji, zobacz Zmiany między zabezpieczeniami usług IIS6 i IIS7, zabezpieczeniami platformy sieci Web i Opis autoryzacji adresu URL usług IIS7.
Krótko mówiąc, w wersjach wcześniejszych niż IIS 7 można używać uwierzytelniania formularzy tylko do ochrony zasobów obsługiwanych przez środowisko uruchomieniowe ASP.NET. Podobnie reguły autoryzacji adresów URL są stosowane tylko do zasobów obsługiwanych przez środowisko uruchomieniowe ASP.NET. Jednak w usługach IIS 7 można zintegrować moduł FormsAuthenticationModule i UrlAuthorizationModule z potokiem HTTP usług IIS, rozszerzając w ten sposób tę funkcję na wszystkie żądania.
Krok 1. Tworzenie witryny internetowej ASP.NET dla tej serii samouczków
Aby dotrzeć do najszerszych możliwych odbiorców, witryna internetowa ASP.NET, którą utworzymy w tej serii, zostanie utworzona za pomocą bezpłatnej wersji programu Visual Studio 2008, Visual Web Developer 2008. Zaimplementujemy SqlMembershipProvider magazyn użytkowników w bazie danych programu Microsoft SQL Server 2005 Express Edition . Jeśli używasz programu Visual Studio 2005 lub innej wersji programu Visual Studio 2008 lub PROGRAMU SQL Server, nie martw się — kroki będą prawie identyczne, a wszelkie nietrywialne różnice zostaną wskazane.
Uwaga / Notatka
Demonstracyjna aplikacja internetowa używana w każdym samouczku jest dostępna do pobrania. Ta aplikacja do pobrania została utworzona za pomocą programu Visual Web Developer 2008 przeznaczonego dla programu .NET Framework w wersji 3.5. Ponieważ aplikacja jest przeznaczona dla platformy .NET 3.5, jej plik Web.config zawiera dodatkowe elementy konfiguracji specyficzne dla wersji 3.5. Krótko mówiąc, jeśli nie masz jeszcze na komputerze zainstalowanej .NET 3.5, pobierana aplikacja internetowa nie będzie działać bez wcześniejszego usunięcia znaczników specyficznych dla wersji 3.5 z Web.config.
Aby można było skonfigurować uwierzytelnianie formularzy, najpierw potrzebujemy witryny internetowej ASP.NET. Zacznij od utworzenia nowej witryny internetowej ASP.NET opartej na systemie plików. Aby to osiągnąć, uruchom program Visual Web Developer, a następnie przejdź do menu Plik i wybierz pozycję Nowa witryna sieci Web, wyświetlając okno dialogowe Nowa witryna sieci Web. Wybierz szablon witryny sieci Web ASP.NET, ustaw listę rozwijaną Lokalizacja na System plików, wybierz folder do umieszczenia witryny internetowej i ustaw język na C#. Spowoduje to utworzenie nowej witryny sieci Web ze stroną Default.aspx ASP.NET, folderem App_Data i plikiem Web.config.
Uwaga / Notatka
Program Visual Studio obsługuje dwa tryby zarządzania projektami: projekty witryn sieci Web i projekty aplikacji internetowych. Projekty witryn sieci Web nie zawierają pliku projektu, natomiast projekty aplikacji internetowych naśladują architekturę projektu w programie Visual Studio .NET 2002/2003 — zawierają plik projektu i skompilują kod źródłowy projektu w jednym zestawie, który znajduje się w folderze /bin. Program Visual Studio 2005 początkowo obsługiwał tylko projekty witryn sieci Web, chociaż model projektu aplikacji internetowej został przywrócony z dodatkiem Service Pack 1; Program Visual Studio 2008 oferuje oba modele projektów. Wersje Visual Web Developer 2005 i 2008 obsługują jednak tylko projekty witryn sieci Web. Będę używać modelu projektu witryny sieci Web. Jeśli używasz wersji innej niż Express i zamiast tego chcesz użyć modelu projektu aplikacji internetowej , możesz to zrobić, ale pamiętaj, że mogą wystąpić pewne rozbieżności między tym, co widzisz na ekranie, a czynnościami, które należy wykonać w porównaniu z wyświetlanymi zrzutami ekranu i instrukcjami podanymi w tych samouczkach.
Rysunek 2. Tworzenie nowego pliku System-Based dla strony internetowej (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Dodawanie strony wzorcowej
Następnie dodaj nową stronę wzorcową do witryny w katalogu głównym o nazwie Site.master. Strony wzorcowe umożliwiają deweloperowi strony zdefiniowanie szablonu dla całej witryny, który można zastosować do ASP.NET stron. Główną zaletą stron wzorcowych jest to, że ogólny wygląd witryny można zdefiniować w jednej lokalizacji, co ułatwia aktualizowanie lub dostosowywanie układu witryny.
Rysunek 3. Dodawanie strony wzorcowej o nazwie Site.master do witryny sieci Web (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Zdefiniuj układ strony całej witryny tutaj na stronie wzorcowej. Możesz użyć widoku Projekt i dodać dowolne potrzebne kontrolki Układu lub Sieci Web, albo ręcznie dodać znaczniki w widoku Źródło. Układ strony wzorcowej został ustrukturyzowany tak, aby naśladował układ używany w serii samouczków Praca z danymi w ASP.NET 2.0 (patrz Rysunek 4). Strona wzorcowa używa kaskadowych arkuszy stylów do pozycjonowania i stylizacji z ustawieniami CSS zdefiniowanymi w pliku Style.css (który jest dołączony do powiązanego pliku do pobrania tego samouczka). Chociaż nie można odróżnić na podstawie znacznika pokazanego poniżej, reguły CSS są zdefiniowane w taki sposób, że zawartość <div> nawigacji jest absolutnie pozycjonowana tak, aby pojawia się po lewej stronie i ma stałą szerokość 200 pikseli.
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Site.master.cs" Inherits="Site" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Forms Authentication, Authorization, and User Accounts</title>
<link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="wrapper">
<form id="form1" runat="server">
<div id="header">
<span class="title">User Account Tutorials</span>
</div>
<div id="content">
<asp:contentplaceholder id="MainContent" runat="server">
<!-- Page-specific content will go here... -->
</asp:contentplaceholder>
</div>
<div id="navigation">
TODO: Menu will go here...
</div>
</form>
</div>
</body>
</html>
Strona wzorcowa definiuje zarówno statyczny układ strony, jak i regiony, które mogą być edytowane przez strony ASP.NET korzystające ze strony wzorcowej. Te edytowalne regiony zawartości są wskazywane przez kontrolę ContentPlaceHolder, która jest widoczna wewnątrz elementu <div> zawartości. Nasza strona wzorcowa ma jeden ContentPlaceHolder element (MainContent), ale strona wzorcowa może mieć wiele symboli ContentPlaceHolder.
Po wprowadzeniu powyższych znaczników, przełączenie na widok projektu pokazuje układ strony wzorcowej. Wszystkie strony ASP.NET korzystające z tej strony wzorcowej będą miały ten jednolity układ z możliwością określenia znaczników dla MainContent regionu.
Rysunek 4. Strona wzorcowa po wyświetleniu w widoku projektu (kliknij, aby wyświetlić obraz pełnowymiarowy)
Tworzenie stron zawartości
Na tym etapie mamy stronę Default.aspx w naszej witrynie internetowej, ale nie używa ona właśnie utworzonej strony wzorcowej. Chociaż istnieje możliwość manipulowania deklaratywnym znacznikiem strony internetowej w celu użycia strony wzorcowej, jeśli strona nie zawiera jeszcze żadnej zawartości, łatwiej jest usunąć stronę i ponownie dodać ją do projektu, określając stronę wzorcową do użycia. Dlatego zacznij od usunięcia Default.aspx z projektu.
Następnie kliknij prawym przyciskiem myszy nazwę projektu w Eksploratorze rozwiązań i wybierz opcję dodania nowego formularza internetowego o nazwie Default.aspx. Tym razem zaznacz pole wyboru "Wybierz stronę wzorcową" i wybierz stronę wzorcową Site.master z listy.
Rysunek 5. Dodawanie nowej strony Default.aspx Wybieranie strony wzorcowej (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 6. Używanie strony wzorcowej Site.master
Uwaga / Notatka
Jeśli używasz modelu projektu aplikacji internetowej, okno dialogowe Dodawanie nowego elementu nie zawiera pola wyboru "Wybierz stronę wzorcową". Zamiast tego należy dodać element typu "Formularz zawartości sieci Web". Po wybraniu "Formularz zawartości sieci Web" i kliknięciu Dodaj, Visual Studio wyświetli to samo okno dialogowe Wybieranie wzorca pokazane na rysunku 6.
Znacznik deklaratywny nowej strony Default.aspx zawiera jedynie dyrektywę @Page określającą ścieżkę do pliku strony wzorcowej oraz kontrolkę zawartości dla MainContent ContentPlaceHolder strony wzorcowej.
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
</asp:Content>
Na razie pozostaw Default.aspx puste. Wrócimy do niego w dalszej części tego samouczka, aby dodać zawartość.
Uwaga / Notatka
Nasza strona wzorcowa zawiera sekcję menu lub inny interfejs nawigacyjny. W przyszłym samouczku utworzymy taki interfejs.
Krok 2. Włączanie uwierzytelniania formularzy
Po utworzeniu witryny internetowej ASP.NET następnym zadaniem jest włączenie uwierzytelniania formularzy. Konfiguracja uwierzytelniania aplikacji jest określana za pośrednictwem <authentication> elementu w Web.config. Element <authentication> zawiera jeden atrybut o nazwie mode, który określa model uwierzytelniania używany przez aplikację. Ten atrybut może mieć jedną z następujących czterech wartości:
- Windows, zgodnie z opisem w poprzednim samouczku, gdy aplikacja korzysta z uwierzytelniania Windows, serwer sieciowy jest odpowiedzialny za uwierzytelnianie osoby odwiedzającej, a zwykle odbywa się to poprzez uwierzytelnianie podstawowe, typu Digest lub zintegrowane uwierzytelnianie Windows.
- Formularze — użytkownicy są uwierzytelniani za pośrednictwem formularza na stronie internetowej.
- Passport — użytkownicy są uwierzytelniani przy użyciu usługi Microsoft Passport Network.
- Brak — nie jest używany żaden model uwierzytelniania; wszyscy odwiedzający są anonimowi.
Domyślnie ASP.NET aplikacje używają uwierzytelniania systemu Windows. Aby zmienić typ uwierzytelniania na uwierzytelnianie formularzy, musimy zmodyfikować <authentication> atrybut mode elementu na Formularze.
Jeśli projekt nie zawiera jeszcze pliku Web.config, dodaj go teraz, klikając prawym przyciskiem myszy nazwę projektu w Eksploratorze rozwiązań, wybierając polecenie Dodaj nowy element, a następnie dodając plik konfiguracji sieci Web.
Rysunek 7. Jeśli projekt nie zawiera jeszcze Web.config, dodaj go teraz (kliknij, aby wyświetlić obraz pełnowymiarowy)
Następnie znajdź <authentication> element i zaktualizuj go, aby używał uwierzytelniania formularzy. Po tej zmianie formatowanie pliku Web.config powinno wyglądać podobnie do następującego:
<configuration>
<system.web>
... Unrelated configuration settings and comments removed for brevity ...
<!--
The <authentication> section enables configuration
of the security authentication mode used by
ASP.NET to identify an incoming user.
-->
<authentication mode="Forms" />
</system.web>
</configuration>
Uwaga / Notatka
Ponieważ Web.config jest plikiem XML, wielkość liter jest ważna. Upewnij się, że atrybut mode jest ustawiony na 'Forms' z dużą literą "F". Jeśli użyjesz innego formatu wielkości liter, takiego jak "formularze", otrzymasz błąd konfiguracji podczas odwiedzania witryny za pośrednictwem przeglądarki.
Element <authentication> może opcjonalnie zawierać element podrzędny <forms> zawierający ustawienia specyficzne dla uwierzytelniania formularzy. Na razie użyjemy tylko domyślnych ustawień uwierzytelniania formularzy. Bardziej szczegółowo omówimy element podrzędny <forms> w następnym samouczku.
Krok 3. Tworzenie strony logowania
Aby obsługiwać uwierzytelnianie formularzy, nasza witryna internetowa wymaga strony logowania. Zgodnie z opisem w sekcji FormsAuthenticationModule "Opis przepływu pracy uwierzytelniania formularzy" program automatycznie przekierowuje użytkownika do strony logowania, jeśli spróbuje uzyskać dostęp do strony, która nie jest autoryzowana do wyświetlania. Istnieją również ASP.NET kontrolki sieci Web, które będą wyświetlać link do strony logowania użytkownikom anonimowym. To pytanie brzmi: "Jaki jest adres URL strony logowania?"
Domyślnie system uwierzytelniania formularzy oczekuje, że strona logowania zostanie nazwana Login.aspx i umieszczona w katalogu głównym aplikacji internetowej. Jeśli chcesz użyć innego adresu URL strony logowania, możesz to zrobić, określając go w Web.config. Pokażemy, jak to zrobić w następnym samouczku.
Strona logowania ma trzy obowiązki:
- Podaj interfejs, który umożliwia odwiedzającym wprowadzanie poświadczeń.
- Ustal, czy przesłane poświadczenia są prawidłowe.
- Zaloguj użytkownika, tworząc token autoryzacji formularzy.
Tworzenie interfejsu użytkownika strony logowania
Zacznijmy od pierwszego zadania. Dodaj nową stronę ASP.NET do katalogu głównego witryny o nazwie Login.aspx i skojarz ją ze stroną wzorcową Site.master.
Rysunek 8. Dodawanie nowej strony ASP.NET o nazwie Login.aspx (kliknij, aby wyświetlić obraz pełnowymiarowy)
Typowy interfejs strony logowania składa się z dwóch skrzynek tekstowych — jednej dla nazwy użytkownika, jednej dla hasła — i przycisku do przesłania formularza. Witryny internetowe często zawierają pole wyboru "Zapamiętaj mnie", które, jeśli zostanie zaznaczone, umożliwia zapamiętanie biletu uwierzytelniania nawet po ponownym uruchomieniu przeglądarki.
Dodaj dwa pola tekstowe do Login.aspx i ustaw ich ID właściwości odpowiednio na UserName i Password. Ustaw również właściwość Password TextMode na Hasło. Następnie dodaj kontrolkę CheckBox, ustawiając jej ID właściwość na RememberMe i jej Text właściwość na "Remember Me". Następnie dodaj przycisk o nazwie LoginButton, którego Text właściwość jest ustawiona na "Login". Na koniec dodaj kontrolkę Etykieta sieci Web i ustaw jej właściwość ID na InvalidCredentialsMessage, jej właściwość Text na "Nazwa użytkownika lub hasło jest nieprawidłowe. Spróbuj ponownie.", jego właściwość ForeColor na Red, a właściwość Visible na False.
Na tym etapie ekran powinien wyglądać podobnie do zrzutu ekranu na rysunku 9, a składnia deklaratywna strony powinna wyglądać następująco:
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
<h1>
Login</h1>
<p>
Username:
<asp:TextBox ID="UserName" runat="server"></asp:TextBox></p>
<p>
Password:
<asp:TextBox ID="Password" runat="server" TextMode="Password"></asp:TextBox></p>
<p>
<asp:CheckBox ID="RememberMe" runat="server" Text="Remember Me" /> </p>
<p>
<asp:Button ID="LoginButton" runat="server" Text="Login" OnClick="LoginButton_Click" /> </p>
<p>
<asp:Label ID="InvalidCredentialsMessage" runat="server" ForeColor="Red" Text="Your username or password is invalid. Please try again."
Visible="False"></asp:Label> </p>
</asp:Content>
Rysunek 9. Strona logowania zawiera dwa pola tekstowe, pole wyboru, przycisk i etykietę (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Na koniec utwórz procedurę obsługi dla zdarzenia Click przycisku LoginButton. W Designerze wystarczy kliknąć dwukrotnie kontrolkę Przycisk, aby utworzyć tę obsługę zdarzeń.
Określanie, czy podane poświadczenia są prawidłowe
Teraz musimy zaimplementować zadanie 2 w obsłudze zdarzenia kliknięcia przycisku — określenie, czy podane poświadczenia są prawidłowe. Aby to zrobić, musi istnieć magazyn użytkownika, który przechowuje wszystkie poświadczenia użytkowników, aby można było określić, czy podane poświadczenia są zgodne z dowolnymi znanymi poświadczeniami.
Przed ASP.NET 2.0 deweloperzy byli odpowiedzialni za zaimplementowanie zarówno własnych repozytoriów użytkowników, jak i przygotowanie kodu w celu weryfikacji podanych poświadczeń z repozytorium. Większość deweloperów implementuje magazyn użytkowników w bazie danych, tworząc tabelę o nazwie Users z kolumnami takimi jak UserName, Password, Email, LastLoginDate itd. Ta tabela zawiera jeden rekord na konto użytkownika. Zweryfikowanie podanych poświadczeń użytkownika wymagałoby odpytowania bazy danych pod kątem pasującej nazwy użytkownika, a następnie upewnienia się, że hasło w bazie danych odpowiada podanemu hasłem.
W przypadku ASP.NET 2.0 deweloperzy powinni zarządzać magazynem użytkowników za pomocą jednego z dostawców członkostwa. W tej serii samouczków będziemy używać dostawcy SqlMembershipProvider, który wykorzystuje bazę danych SQL Server jako magazyn użytkowników. W przypadku korzystania z klasy SqlMembershipProvider musimy zaimplementować określony schemat bazy danych zawierający tabele, widoki i procedury składowane oczekiwane przez dostawcę. Sprawdzimy, jak zaimplementować ten schemat w samouczku Tworzenie schematu członkostwa w programie SQL Server . W przypadku dostawcy Membership weryfikowanie poświadczeń użytkownika jest tak proste, jak wywołanie metody ValidateUser(nazwa użytkownika, hasło)klasy Membership, która zwraca wartość logiczną wskazującą, czy ważna jest kombinacja nazwy użytkownika i hasła. Ponieważ nie zaimplementowaliśmy jeszcze magazynu użytkowników SqlMembershipProvider, nie możemy w tej chwili użyć metody ValidateUser klasy Membership.
Zamiast zająć trochę czasu na utworzenie własnej niestandardowej tabeli bazy danych Users (która byłaby przestarzała po zaimplementowaniu obiektu SqlMembershipProvider), zamiast tego zakodujmy prawidłowe poświadczenia na samej stronie logowania. W procedurze obsługi zdarzenia Click dla elementu LoginButton dodaj poniższy kod:
protected void LoginButton_Click(object sender, EventArgs e)
{
// Three valid username/password pairs: Scott/password, Jisun/password, and Sam/password.
string[] users = { "Scott", "Jisun", "Sam" };
string[] passwords = { "password", "password", "password" };
for (int i = 0; i < users.Length; i++)
{
bool validUsername = (string.Compare(UserName.Text, users[i], true) == 0);
bool validPassword = (string.Compare(Password.Text, passwords[i], false) == 0);
if (validUsername && validPassword)
{
// TODO: Log in the user...
// TODO: Redirect them to the appropriate page
}
}
// If we reach here, the user's credentials were invalid
InvalidCredentialsMessage.Visible = true;
}
Jak widać, istnieją trzy prawidłowe konta użytkowników — Scott, Jisun i Sam — a wszystkie trzy mają to samo hasło ("hasło"). Kod iteruje przez tablice użytkowników i haseł, szukając dopasowania prawidłowej nazwy użytkownika i hasła. Jeśli zarówno nazwa użytkownika, jak i hasło są prawidłowe, musimy zalogować użytkownika, a następnie przekierować je do odpowiedniej strony. Jeśli poświadczenia są nieprawidłowe, zostanie wyświetlona etykieta InvalidCredentialsMessage.
Kiedy użytkownik wprowadza prawidłowe poświadczenia, wspomniałem, że są następnie przekierowywani do "odpowiedniej strony". Jaka jest jednak odpowiednia strona? Pamiętaj, że gdy użytkownik odwiedza stronę, która nie jest autoryzowana do wyświetlania, moduł FormsAuthenticationModule automatycznie przekierowuje je do strony logowania. W ten sposób zawiera żądany adres URL w ciągu zapytania za pośrednictwem parametru ReturnUrl. Oznacza to, że jeśli użytkownik próbował odwiedzić ProtectedPage.aspx i nie był autoryzowany do tego celu, moduł FormsAuthenticationModule przekierowuje go do:
Login.aspx? ReturnUrl=ProtectedPage.aspx
Po pomyślnym zalogowaniu użytkownik powinien zostać przekierowany z powrotem do ProtectedPage.aspx. Alternatywnie użytkownicy mogą odwiedzać stronę logowania na własną rękę. W takim przypadku po zalogowaniu się użytkownika powinny zostać wysłane do strony Default.aspx folderu głównego.
Logowanie użytkownika
Zakładając, że podane poświadczenia są prawidłowe, musimy utworzyć bilet uwierzytelniania formularzy, logując się w ten sposób do witryny użytkownika. Klasa FormsAuthentication w przestrzeni nazw System.Web.Security udostępnia metody assortowane do logowania i wylogowywania użytkowników za pośrednictwem systemu uwierzytelniania formularzy. Chociaż w klasie FormsAuthentication istnieje kilka metod, te trzy, które interesują nas w tym momencie, to:
- GetAuthCookie(nazwa użytkownika, persistCookie) — tworzy bilet uwierzytelniania formularzy dla podanej nazwy użytkownika. Następnie ta metoda tworzy i zwraca obiekt HttpCookie, który przechowuje zawartość biletu uwierzytelniania. Jeśli wartość persistCookie ma wartość true, zostanie utworzony trwały plik cookie.
- SetAuthCookie(nazwa użytkownika, persistCookie) — wywołuje metodę GetAuthCookie(username, persistCookie), aby wygenerować plik cookie uwierzytelniania formularzy. Następnie ta metoda dodaje plik cookie zwrócony przez metodę GetAuthCookie do kolekcji plików cookie (zakładając, że używane jest uwierzytelnianie oparte na plikach cookie; w przeciwnym razie ta metoda wywołuje wewnętrzną klasę, która obsługuje logikę biletów bez plików cookie).
- RedirectFromLoginPage(nazwa użytkownika, persistCookie) — ta metoda wywołuje metodę SetAuthCookie(nazwa użytkownika, persistCookie), a następnie przekierowuje użytkownika do odpowiedniej strony.
GetAuthCookie jest przydatne, gdy musisz zmodyfikować token uwierzytelniania przed zapisaniem ciasteczka w kolekcji ciasteczek. UstawienieAuthCookie jest przydatne, jeśli chcesz utworzyć bilet uwierzytelniania formularzy i dodać go do kolekcji Cookies, ale nie chcesz przekierowywać użytkownika do odpowiedniej strony. Być może chcesz zachować je na stronie logowania lub wysłać je do innej strony.
Ponieważ chcemy zalogować użytkownika i przekierować ich do odpowiedniej strony, użyjmy RedirectFromLoginPage. Zaktualizuj procedurę obsługi zdarzeń Click elementu LoginButton, zastępując dwa skomentowane wiersze TODO następującym wierszem kodu:
FormsAuthentication.RedirectFromLoginPage(UserName.Text, RememberMe.Checked);
Podczas tworzenia biletu uwierzytelniania formularzy korzystamy z właściwości Text pola tekstowego UserName jako parametru nazwy użytkownika w bilecie uwierzytelniania oraz ze zaznaczonego stanu pola wyboru RememberMe jako parametru persistCookie.
Aby przetestować stronę logowania, odwiedź ją w przeglądarce. Zacznij od wprowadzenia nieprawidłowych poświadczeń, takich jak nazwa użytkownika "Nope" i hasło "błędne". Po kliknięciu przycisku Zaloguj nastąpi przeładowanie strony i zostanie wyświetlony komunikat: Niepoprawne dane logowania.
Rysunek 10. Etykieta InvalidCredentialsMessage jest wyświetlana podczas wprowadzania nieprawidłowych poświadczeń (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Następnie wprowadź prawidłowe poświadczenia i kliknij przycisk Zaloguj. Tym razem, gdy następuje powrót, zostanie utworzony token uwierzytelniania formularzy i nastąpi automatyczne przekierowanie z powrotem do Default.aspx. W tym momencie zalogowano się do witryny internetowej, chociaż nie ma żadnych wskazówek wizualnych wskazujących, że użytkownik jest obecnie zalogowany. W kroku 4 zobaczymy, jak programowo określić, czy użytkownik jest zalogowany, czy nie, a także jak zidentyfikować użytkownika odwiedzającego stronę.
Krok 5 analizuje techniki wylogowywania użytkownika z witryny internetowej.
Zabezpieczanie strony logowania
Gdy użytkownik wprowadzi swoje poświadczenia i prześle formularz strony logowania, poświadczenia — w tym jej hasło — są przesyłane przez Internet do serwera internetowego w postaci zwykłego tekstu. Oznacza to, że każdy haker wąchając ruch sieciowy może zobaczyć nazwę użytkownika i hasło. Aby temu zapobiec, ważne jest szyfrowanie ruchu sieciowego przy użyciu protokołu Secure Socket Layer (SSL). Dzięki temu poświadczenia (a także znaczniki HTML całej strony) będą szyfrowane od momentu opuszczenia przeglądarki do momentu odebrania ich przez serwer sieciowy.
Jeśli witryna internetowa nie zawiera poufnych informacji, należy użyć protokołu SSL tylko na stronie logowania i na innych stronach, na których hasło użytkownika zostałoby wysłane za pośrednictwem przewodu w postaci zwykłego tekstu. Nie musisz martwić się o zabezpieczenie biletu uwierzytelniania formularzy, ponieważ domyślnie jest on szyfrowany i podpisany cyfrowo (aby zapobiec manipulacji). Bardziej szczegółowe omówienie bezpieczeństwa biletów uwierzytelniania za pomocą formularzy zostało zaprezentowane w poniższym samouczku.
Uwaga / Notatka
Wiele witryn finansowych i medycznych jest skonfigurowanych do używania protokołu SSL na wszystkich stronach dostępnych dla uwierzytelnionych użytkowników. Jeśli tworzysz taką witrynę internetową, możesz skonfigurować system uwierzytelniania formularzy tak, aby bilet uwierzytelniania formularzy był przesyłany tylko za pośrednictwem bezpiecznego połączenia.
Krok 4. Wykrywanie uwierzytelnionych odwiedzających i określanie ich tożsamości
W tym momencie włączyliśmy uwierzytelnianie formularzy i utworzyliśmy podstawową stronę logowania, ale jeszcze sprawdziliśmy, jak można określić, czy użytkownik jest uwierzytelniony, czy anonimowy. W niektórych scenariuszach możemy chcieć wyświetlić różne dane lub informacje w zależności od tego, czy uwierzytelniony lub anonimowy użytkownik odwiedza stronę. Ponadto często musimy znać tożsamość uwierzytelnionego użytkownika.
Rozszerzmy istniejącą stronę Default.aspx, aby zilustrować te techniki. W Default.aspx dodaj dwie kontrolki Panel, jedna o nazwie AuthenticatedMessagePanel i druga o nazwie AnonymousMessagePanel. Dodaj kontrolkę "Etykieta" o nazwie WelcomeBackMessage w pierwszym panelu. W drugim panelu dodaj kontrolkę HyperLink, ustaw jej właściwość Text na wartość "Log In" i jej właściwość NavigateUrl na wartość "~/Login.aspx". W tym momencie znaczniki deklaratywne dla Default.aspx powinny wyglądać podobnie do następujących:
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
<asp:Panel runat="server" ID="AuthenticatedMessagePanel">
<asp:Label runat="server" ID="WelcomeBackMessage"></asp:Label>
</asp:Panel>
<asp:Panel runat="Server" ID="AnonymousMessagePanel">
<asp:HyperLink runat="server" ID="lnkLogin" Text="Log In" NavigateUrl="~/Login.aspx"></asp:HyperLink>
</asp:Panel>
</asp:Content>
Jak zapewne już się domyśliłeś, chodzi o to, aby wyświetlić tylko AuthenticatedMessagePanel dla uwierzytelnionych odwiedzających i tylko AnonymousMessagePanel dla anonimowych odwiedzających. Aby to osiągnąć, musimy ustawić właściwości Widoczne dla tych paneli w zależności od tego, czy użytkownik jest zalogowany, czy nie.
Właściwość Request.IsAuthenticated zwraca wartość logiczną wskazującą, czy żądanie zostało uwierzytelnione. Wprowadź następujący kod w kodzie obsługi zdarzeń Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
WelcomeBackMessage.Text = "Welcome back!";
AuthenticatedMessagePanel.Visible = true;
AnonymousMessagePanel.Visible = false;
}
else
{
AuthenticatedMessagePanel.Visible = false;
AnonymousMessagePanel.Visible = true;
}
}
Korzystając z tego kodu, odwiedź Default.aspx za pośrednictwem przeglądarki. Przy założeniu, że jeszcze się nie zalogowałeś, zobaczysz link do strony logowania (zobacz Rysunek 11). Kliknij ten link i zaloguj się do witryny. Jak pokazano w kroku 3, po wprowadzeniu poświadczeń nastąpi powrót do Default.aspx, ale tym razem na stronie zostanie wyświetlony komunikat "Witamy z powrotem!" (zobacz Rysunek 12).
Rysunek 11. Podczas odwiedzania anonimowo jest wyświetlany link logowania
Rysunek 12. Użytkownikom uwierzytelnionym wyświetlany jest komunikat "Witamy z powrotem!"
Możemy określić tożsamość aktualnie zalogowanego użytkownika za pośrednictwem właściwości Userobiektu HttpContext. Obiekt HttpContext reprezentuje informacje o bieżącym żądaniu i jest domem dla takich typowych obiektów ASP.NET jak odpowiedź, żądanie i sesja, między innymi. Właściwość User reprezentuje kontekst zabezpieczeń bieżącego żądania HTTP i implementuje interfejs IPrincipal.
Właściwość User jest ustawiana przez moduł FormsAuthenticationModule. W szczególności, gdy moduł FormsAuthenticationModule znajdzie bilet uwierzytelniania formularzy w żądaniu przychodzącym, tworzy nowy obiekt GenericPrincipal i przypisuje go do właściwości User.
Obiekty główne (na przykład GenericPrincipal) zawierają informacje o tożsamości użytkownika i rolach, do których należą. Interfejs IPrincipal definiuje dwóch członków.
- IsInRole(roleName) — metoda zwracająca wartość logiczną wskazującą, czy podmiot należy do określonej roli.
- Identity — właściwość zwracająca obiekt implementujący interfejs IIdentity. Interfejs IIdentity definiuje trzy właściwości: AuthenticationType, IsAuthenticated i Name.
Możemy określić nazwę bieżącego gościa przy użyciu następującego kodu:
ciąg currentUsersName = User.Identity.Name;
W przypadku korzystania z uwierzytelniania formularzy obiekt FormsIdentity jest tworzony dla właściwości Identity obiektu GenericPrincipal. Klasa FormsIdentity zawsze zwraca ciąg "Forms" dla właściwości AuthenticationType i true dla właściwości IsAuthenticated. Właściwość Name zwraca nazwę użytkownika określoną podczas tworzenia biletu uwierzytelniania form. Oprócz tych trzech właściwości, FormsIdentity obejmuje dostęp do bazowego biletu uwierzytelniania za pośrednictwem właściwości Ticket. Właściwość Ticket zwraca obiekt typu FormsAuthenticationTicket, który ma właściwości takie jak Expiration, IsPersistent, IssueDate, Name itd.
Ważną kwestią do zapamiętania jest to, że parametr nazwy użytkownika określony w metodach FormsAuthentication.GetAuthCookie(username, persistCookie), FormsAuthentication.SetAuthCookie(username, persistCookie) i FormsAuthentication.RedirectFromLoginPage(username, persistCookie) jest tą samą wartością zwracaną przez User.Identity.Name. Ponadto bilet uwierzytelniania utworzony przez te metody jest dostępny przez rzutowanie elementu User.Identity do obiektu FormsIdentity, a następnie uzyskiwanie dostępu do właściwości Ticket:
FormsIdentity ident = User.Identity as FormsIdentity;
FormsAuthenticationTicket authTicket = ident.Ticket;
Zapewnijmy bardziej spersonalizowaną wiadomość w Default.aspx. Zaktualizuj program obsługi zdarzeń Page_Load, aby przypisać ciąg "Welcome back, username!" do właściwości Text etykiety WelcomeBackMessage.
WelcomeBackMessage.Text = "Witamy ponownie, " + User.Identity.Name + "!";
Rysunek 13 przedstawia efekt tej modyfikacji (podczas logowania się jako użytkownik Scott).
Rysunek 13. Komunikat powitalny zawiera nazwę aktualnie zalogowanego użytkownika
Używanie kontrolek LoginView i LoginName
Wyświetlanie innej zawartości dla uwierzytelnionych i anonimowych użytkowników jest typowym wymaganiem; dlatego wyświetla nazwę aktualnie zalogowanego użytkownika. Z tego powodu ASP.NET zawiera dwie kontrolki sieci Web, które zapewniają te same funkcje przedstawione na rysunku 13, ale bez konieczności pisania jednego wiersza kodu.
Kontrolka LoginView to oparta na szablonach kontrolka sieci Web, która ułatwia wyświetlanie różnych danych dla uwierzytelnionych i anonimowych użytkowników. Element LoginView zawiera dwa wstępnie zdefiniowane szablony:
- AnonymousTemplate — każdy znacznik dodany do tego szablonu jest wyświetlany tylko dla anonimowych odwiedzających.
- LoggedInTemplate — znaczniki tego szablonu są wyświetlane tylko dla uwierzytelnionych użytkowników.
Dodajmy kontrolkę LoginView do strony głównej witryny Site.master. Zamiast dodawać tylko kontrolkę LoginView, dodajmy jednak zarówno nową kontrolkę ContentPlaceHolder, jak i umieśćmy kontrolkę LoginView w ramach tej nowej kontrolki ContentPlaceHolder. Uzasadnienie tej decyzji stanie się widoczne wkrótce.
Uwaga / Notatka
Oprócz kontrolki AnonymousTemplate i LoggedInTemplate kontrolka LoginView może zawierać szablony specyficzne dla roli. Szablony specyficzne dla ról pokazują znaczniki tylko dla tych użytkowników, którzy należą do określonej roli. W przyszłym samouczku zapoznamy się z funkcjami opartymi na rolach kontrolki LoginView.
Zacznij od dodania elementu ContentPlaceHolder o nazwie LoginContent do strony wzorcowej w elemencie <div> nawigacji. Możesz po prostu przeciągnąć kontrolkę ContentPlaceHolder z Przybornika do widoku kodu źródłowego, umieszczając wynikowy znacznik tuż nad tekstem "TODO: Menu tutaj się znajdzie...".
<div id="navigation">
<asp:ContentPlaceHolder ID="LoginContent" runat="server">
</asp:ContentPlaceHolder>
TODO: Menu will go here...
</div>
Następnie dodaj kontrolkę LoginView w elemencie LoginContent ContentPlaceHolder. Zawartość umieszczona w kontrolkach ContentPlaceHolder strony wzorcowej jest uważana za domyślną zawartość elementu ContentPlaceHolder. Oznacza to, że ASP.NET strony korzystające z tej strony wzorcowej mogą określać własną zawartość dla każdego elementu ContentPlaceHolder lub używać domyślnej zawartości strony wzorcowej.
Kontrolki LoginView i inne kontrolki związane z logowaniem znajdują się na karcie Logowanie przybornika.
Rysunek 14: Kontrolka LoginView w przyborniku
Następnie dodaj dwa < br /> elementy bezpośrednio po kontrolce LoginView, ale nadal w elemencie ContentPlaceHolder. Na tym etapie znacznik elementu <div> nawigacji powinien wyglądać następująco:
<div id="navigation">
<asp:ContentPlaceHolder ID="LoginContent" runat="server">
<asp:LoginView ID="LoginView1" runat="server">
</asp:LoginView>
<br /><br />
</asp:ContentPlaceHolder>
TODO: Menu will go here...
</div>
Szablony LoginView można zdefiniować za pomocą projektanta lub deklaratywnego kodu. W projektancie Visual Studio rozwiń tag inteligentny LoginView, w którym znajduje się lista skonfigurowanych szablonów jako lista rozwijana. Wpisz tekst "Hello, stranger" w polu AnonymousTemplate; Następnie dodaj kontrolkę HyperLink i ustaw jej właściwości Text i NavigateUrl odpowiednio na "Log In" i "~/Login.aspx".
Po skonfigurowaniu elementu AnonymousTemplate przejdź do elementu LoggedInTemplate i wprowadź tekst "Witamy z powrotem". Następnie przeciągnij kontrolkę LoginName z Przybornika do elementu LoggedInTemplate, umieszczając ją natychmiast po tekście "Witamy ponownie, ". Kontrolka LoginName, jak wskazuje jej nazwa, wyświetla nazwę aktualnie zalogowanego użytkownika. Wewnętrznie kontrolka LoginName po prostu wyprowadza właściwość User.Identity.Name
Po dodaniu tych dodatków do szablonów widoku LoginView, znacznik powinien wyglądać podobnie do tego:
<div id="navigation">
<asp:ContentPlaceHolder ID="LoginContent" runat="server">
<asp:LoginView ID="LoginView1" runat="server">
<LoggedInTemplate>
Welcome back,
<asp:LoginName ID="LoginName1" runat="server" />.
</LoggedInTemplate>
<AnonymousTemplate>
Hello, stranger.
<asp:HyperLink ID="lnkLogin" runat="server" NavigateUrl="~/Login.aspx">Log In</asp:HyperLink>
</AnonymousTemplate>
</asp:LoginView>
<br /><br />
</asp:ContentPlaceHolder>
TODO: Menu will go here...
</div>
Oprócz strony wzorcowej Site.master każda strona w naszej witrynie internetowej będzie wyświetlać inny komunikat w zależności od tego, czy użytkownik jest uwierzytelniony. Rysunek 15 przedstawia stronę Default.aspx podczas odwiedzania za pośrednictwem przeglądarki przez użytkownika Jisun. Komunikat "Witaj ponownie, Jisun" jest powtarzany dwa razy: raz w sekcji nawigacji strony wzorcowej po lewej stronie (za pomocą kontrolki LoginView, którą właśnie dodaliśmy) i raz w obszarze zawartości Default.aspx (za pomocą kontrolek Panel i logiki programowania).
Rysunek 15. Kontrolka LoginView wyświetla komunikat "Welcome back, Jisun".
Ponieważ dodaliśmy element LoginView do strony wzorcowej, może ona być wyświetlana na każdej stronie w naszej witrynie. Jednak mogą istnieć strony internetowe, na których nie chcemy wyświetlać tego komunikatu. Jedną z takich stron jest strona logowania, ponieważ link do strony logowania wydaje się tam niedostępny. Ponieważ kontrolka LoginView została umieszczona w kontrolce ContentPlaceHolder na stronie wzorcowej, możemy zastąpić ten domyślny znacznik na naszej stronie zawartości. Otwórz Login.aspx i przejdź do projektanta. Ponieważ nie zdefiniowano jawnie kontrolki Zawartość w Login.aspx dla elementu LoginContent ContentPlaceHolder na stronie wzorcowej, na stronie logowania będą wyświetlane domyślne znaczniki strony wzorcowej dla tego elementu ContentPlaceHolder. Można to zobaczyć za pośrednictwem projektanta — w kontrolce LoginContent ContentPlaceHolder jest wyświetlany domyślny znacznik (kontrolka LoginView).
Rysunek 16. Strona logowania przedstawia domyślną zawartość identyfikatora LoginContent ContentPlaceHolder strony wzorcowej (kliknij, aby wyświetlić obraz pełnowymiarowy)
Aby zastąpić domyślne oznaczenie LoginContent ContentPlaceHolder, po prostu kliknij prawym przyciskiem myszy na region w Projektancie i wybierz opcję Utwórz Zawartość Niestandardową z menu kontekstowego. (W przypadku korzystania z programu Visual Studio 2008 symbol ContentPlaceHolder zawiera tag inteligentny, który po wybraniu oferuje tę samą opcję). Spowoduje to dodanie nowej kontrolki Zawartość do znaczników strony, dzięki czemu możemy zdefiniować niestandardową zawartość dla tej strony. W tym miejscu możesz dodać niestandardowy komunikat, taki jak "Zaloguj się...", ale pozostawmy to pole puste.
Uwaga / Notatka
W programie Visual Studio 2005 tworzenie zawartości niestandardowej powoduje utworzenie pustej kontrolki Zawartość na stronie ASP.NET. Jednak w programie Visual Studio 2008 tworzenie niestandardowej zawartości kopiuje domyślną zawartość strony wzorcowej do nowo utworzonej kontrolki Zawartość. Jeśli używasz programu Visual Studio 2008, po utworzeniu nowej kontrolki Zawartość pamiętaj, aby wyczyścić zawartość skopiowaną ze strony wzorcowej.
Rysunek 17 przedstawia stronę Login.aspx, gdy jest ona odwiedzana w przeglądarce po wprowadzeniu tej zmiany. Należy pamiętać, że nie ma komunikatu "Hello, stranger" ani "Welcome back, nazwa użytkownika" w lewej nawigacji <div>, jak jest przy odwiedzaniu Default.aspx.
Rysunek 17. Strona logowania ukrywa domyślny znacznik LoginContent ContentPlaceHolder (Kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Krok 5. Wylogowanie
W kroku 3 przyjrzeliśmy się utworzeniu strony logowania w celu zalogowania użytkownika na stronie, ale jeszcze nie zobaczyliśmy, jak wylogować użytkownika. Oprócz metod logowania użytkownika, klasa FormsAuthentication udostępnia również metodę SignOut. Metoda SignOut po prostu niszczy bilet uwierzytelniania formularzy, co powoduje wylogowanie użytkownika z witryny.
Oferowanie linku do wylogowania się jest tak powszechną funkcją, że ASP.NET zawiera kontrolkę specjalnie przeznaczoną do wylogowania użytkownika. Kontrolka LoginStatus wyświetla element LinkButton "Login" lub "Logout" w zależności od stanu uwierzytelniania użytkownika. Przyciski LinkButton "Login" są wyświetlane dla użytkowników anonimowych, natomiast przyciski LinkButton "Wyloguj" są pokazywane dla uwierzytelnionych użytkowników. Tekst dla przycisków łącza "Login" i "Logout" można skonfigurować za pomocą właściwości LoginText i LogoutText komponentu LoginStatus.
Kliknięcie przycisku LinkButton „Login” powoduje odświeżenie strony, a następnie przekierowanie na stronę logowania. Kliknięcie "Logout" w LinkButton powoduje, że kontrolka LoginStatus wywołuje metodę FormsAuthentication.SignOff, a następnie przekierowuje użytkownika na stronę. Strona, do której zalogowany użytkownik jest przekierowywany, zależy od właściwości LogoutAction, którą można przypisać do jednej z trzech następujących wartości:
- Odśwież — wartość domyślna; przekierowuje użytkownika do strony, którą właśnie odwiedzali. Jeśli strona, którą odwiedzali, nie zezwala na użytkowników anonimowych, moduł FormsAuthenticationModule automatycznie przekierowuje użytkownika na stronę logowania.
Możesz być ciekaw, dlaczego przekierowanie jest wykonywane tutaj. Jeśli użytkownik chce pozostać na tej samej stronie, dlaczego konieczne jest jawne przekierowanie? Przyczyną jest to, że po kliknięciu przycisku LinkButton "Logoff" użytkownik nadal ma bilet uwierzytelniania formularzy w kolekcji plików cookie. W związku z tym żądanie typu postback jest uwierzytelnionym żądaniem. Kontrolka LoginStatus wywołuje metodę SignOut, ale dzieje się tak po uwierzytelnieniu użytkownika przez moduł FormsAuthenticationModule. W związku z tym jawne przekierowanie powoduje ponowne zażądanie strony przez przeglądarkę. Gdy przeglądarka ponownie zażąda strony, bilet uwierzytelniania formularzy został usunięty, a zatem żądanie przychodzące jest anonimowe.
- Przekierowanie — użytkownik jest przekierowywany do adresu URL określonego przez właściwość LoginStatus's LogoutPageUrl.
- RedirectToLoginPage — użytkownik jest przekierowywany do strony logowania.
Dodajmy kontrolkę LoginStatus do strony wzorcowej i skonfigurujmy ją tak, aby korzystała z opcji Przekierowanie, aby wysłać użytkownika do strony, która wyświetla komunikat z potwierdzeniem wylogowania. Zacznij od utworzenia strony w katalogu głównym o nazwie Logout.aspx. Nie zapomnij skojarzyć tej strony ze stroną wzorcową Site.master. Następnie wprowadź komunikat w znaczniku strony wyjaśniający użytkownikowi, że został wylogowany.
Następnie wróć do strony wzorcowej Site.master i dodaj kontrolkę LoginStatus pod kontrolką LoginView w elemencie LoginContent ContentPlaceHolder. Ustaw właściwość LogoutAction kontrolki LoginStatus na Wartość Redirect i jej właściwość LogoutPageUrl na wartość "~/Logout.aspx".
<div id="navigation">
<asp:ContentPlaceHolder ID="LoginContent" runat="server">
<asp:LoginView ID="LoginView1" runat="server">
<LoggedInTemplate>
Welcome back,
<asp:LoginName ID="LoginName1" runat="server" />.
</LoggedInTemplate>
<AnonymousTemplate>
Hello, stranger.
<asp:HyperLink ID="lnkLogin" runat="server" NavigateUrl="~/Login.aspx">Log In</asp:HyperLink>
</AnonymousTemplate>
</asp:LoginView>
<br />
<asp:LoginStatus ID="LoginStatus1" runat="server" LogoutAction="Redirect" LogoutPageUrl="~/Logout.aspx" />
<br /><br />
</asp:ContentPlaceHolder>
TODO: Menu will go here...
</div>
Ponieważ identyfikator LoginStatus znajduje się poza kontrolką LoginView, będzie wyświetlany zarówno dla użytkowników anonimowych, jak i uwierzytelnionych, ale jest to ok, ponieważ identyfikator LoginStatus poprawnie wyświetli wartość "Login" lub "Logout" LinkButton. Po dodaniu kontrolki LoginStatus funkcja HyperLink "Log In" w elemecie AnonymousTemplate jest nadmiarowa, więc usuń ją.
Rysunek 18 przedstawia Default.aspx, gdy Jisun odwiedza stronę. Zwróć uwagę, że w lewej kolumnie jest wyświetlany komunikat "Witamy z powrotem, Jisun" wraz z linkiem umożliwiającym wylogowanie się. Kliknięcie przycisku LinkButton wylogowania powoduje odświeżenie strony, wylogowuje Jisun z systemu, a następnie przekierowuje ją do Logout.aspx. Jak pokazano na rysunku 19, gdy Jisun osiągnie Logout.aspx, została już wylogowana i dlatego jest anonimowa. W związku z tym lewa kolumna zawiera tekst "Welcome, stranger" i link do strony logowania.
Rysunek 18. Default.aspx wyświetla "Welcome Back, Jisun" wraz z przyciskiem "Wyloguj się" (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Rysunek 19. Logout.aspx pokazuje tekst "Welcome, stranger" wraz z elementem LinkButton "Login" (Kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Uwaga / Notatka
Zachęcam do dostosowania strony Logout.aspx, aby ukryć element LoginContent ContentPlaceHolder na master page (tak jak zrobiliśmy w przypadku Login.aspx w kroku 4). Przyczyną jest to, że link "Login" renderowany przez kontrolkę LoginStatus (pod kontrolką "Hello, stranger") wysyła użytkownika na stronę logowania, przekazując bieżący adres URL w parametrze ReturnUrl querystring. Krótko mówiąc, jeśli użytkownik, który się wylogował, kliknie przycisk LinkButton "Zaloguj się" komponentu LoginStatus, a następnie zaloguje się, będzie przekierowany z powrotem do strony Logout.aspx, co może łatwo mylić użytkownika.
Podsumowanie
W tym samouczku rozpoczęliśmy badanie przepływu pracy uwierzytelniania formularzy, a następnie zwróciliśmy się do implementowania uwierzytelniania formularzy w aplikacji ASP.NET. Uwierzytelnianie formularzy jest obsługiwane przez moduł FormsAuthenticationModule, który ma dwie obowiązki: identyfikowanie użytkowników na podstawie biletu uwierzytelniania formularzy i przekierowywanie nieautoryzowanych użytkowników do strony logowania.
Klasa FormsAuthentication programu .NET Framework zawiera metody tworzenia, sprawdzania i usuwania biletów uwierzytelniania formularzy. Właściwość Request.IsAuthenticated i obiekt User zapewniają dodatkową obsługę programową określania, czy żądanie jest uwierzytelnione, oraz informacje o tożsamości użytkownika. Istnieją również kontrolki LoginView, LoginStatus i LoginName Web, które zapewniają deweloperom szybki, wolny od kodu sposób wykonywania wielu typowych zadań związanych z logowaniem. Te i inne kontrolki sieci Web związane z logowaniem zostaną dokładniej zbadane w przyszłych samouczkach.
Ten samouczek zawiera pobiegliwe omówienie uwierzytelniania formularzy. Nie zbadaliśmy różnorodnych opcji konfiguracji, nie przyjrzeliśmy się, jak działają formularze uwierzytelniania bez plików cookie, ani nie zbadaliśmy, jak ASP.NET chroni zawartość jednostek uwierzytelniania formularzy.
Szczęśliwe programowanie!
Dalsza lektura
Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:
- Zmiany między zabezpieczeniami usług IIS6 i IIS7
- Kontrolki logowania ASP.NET
- Profesjonalne zarządzanie bezpieczeństwem, członkostwem i rolami w ASP.NET 2.0 (ISBN: 978-0-7645-9698-8)
-
Element
<authentication> -
Element
<forms>dla<authentication>
Szkolenie wideo dotyczące tematów zawartych w tym samouczku
Informacje o autorze
Scott Mitchell, autor siedmiu 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. Można go uzyskać pod adresem mitchell@4GuysFromRolla.com.
Specjalne podziękowania...
Ta seria samouczków została omówiona przez wielu przydatnych recenzentów. Głównym recenzentem tego samouczka był [lead reviewer's name]. Ta seria samouczków została przejrzana przez wielu pomocnych recenzentów. Główni recenzenci tego samouczka to Alicja Maziarz, John Suru i Teresa Murphy. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, napisz do mnie na adres mitchell@4GuysFromRolla.com.