Omówienie uwierzytelniania formularzy (C#)

Autor: Scott Mitchell

Uwaga

Ponieważ ten artykuł został napisany, dostawcy ASP.NET członkostwa zostały zastąpione przez usługę ASP.NET Identity. Zdecydowanie zalecamy aktualizowanie aplikacji w celu korzystania z platformy ASP.NET Identity , a nie dostawców członkostwa opisanych w tym artykule. ASP.NET Identity ma wiele zalet w systemie 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
  • 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óra rozpocznie tworzenie w tym samouczku, będzie nadal oparta na kolejnych samouczkach, ponieważ przechodzimy od prostego uwierzytelniania formularzy do członkostwa i ról.

Zobacz ten film wideo, aby uzyskać więcej informacji na ten temat: Korzystanie z uwierzytelniania podstawowego 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óra rozpocznie tworzenie w tym samouczku, będzie nadal oparta na kolejnych samouczkach, ponieważ 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— temat, który omówiliśmy w poprzednim samouczku. W tym celu utworzymy witrynę internetową ASP.NET, za pomocą której przedstawiono koncepcje uwierzytelniania formularzy. Następnie skonfigurujemy witrynę tak, aby korzystała 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, z którą 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. Z tego powodu — i dlatego, że te samouczki opierają się na sobie nawzajem — zachęcamy 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 ASP.NET sieci Web, żądanie zgłasza wiele zdarzeń podczas cyklu życia. Istnieją zdarzenia zgłaszane na samym początku i na samym końcu żądania, 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 dostarczane z wieloma modułami HTTP, które wykonują podstawowe zadania w tle. Dwa wbudowane moduły HTTP, które są szczególnie istotne dla naszej dyskusji:

  • FormsAuthenticationModule — uwierzytelnia użytkownika, sprawdzając bilet uwierzytelniania formularzy, który jest zazwyczaj 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 urząd, konsultując się z regułami autoryzacji określonymi w plikach konfiguracji aplikacji. ASP.NET zawiera FileAuthorizationModule również ten, który określa urząd, konsultując się z żądanymi listami ACL.

Próby FormsAuthenticationModule uwierzytelnienia użytkownika przed wykonaniem UrlAuthorizationModule operacji (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ń przez modalne okno dialogowe. 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 ).

Odpowiedzialność strony logowania polega na ustaleniu, 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óre FormsAuthenticationModule są używane do identyfikowania użytkownika.

Przepływ pracy uwierzytelniania formularzy

Rysunek 1. Przepływ pracy uwierzytelniania formularzy

Pamiętanie biletu uwierzytelniania między wizytami stron

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. Jest to zwykle realizowane przez umieszczenie biletu uwierzytelniania w kolekcji plików cookie użytkownika. Pliki cookie są małymi plikami tekstowymi, które znajdują się na komputerze użytkownika i są przesyłane w nagłówkach HTTP na 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. Gdy użytkownik odwiedza się z publicznego terminalu, prawdopodobieństwo, że bilet uwierzytelniania wygaśnie po zamknięciu przeglądarki. Jednak podczas wizyty w domu ten sam użytkownik może chcieć zapamiętać bilet uwierzytelniania w przeglądarce ponownie, 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 przedstawiono ustawienia limitu czasu biletu uwierzytelniania.

Uwaga

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 mogą używać biletów uwierzytelniania formularzy bez plików cookie. W tym trybie bilet uwierzytelniania jest zakodowany w adresie URL. Przyjrzymy się, kiedy są używane bilety uwierzytelniania bez plików cookie i jak są tworzone i zarządzane w następnym samouczku.

Zakres uwierzytelniania formularzy

Jest FormsAuthenticationModule to kod zarządzany, który jest częścią środowiska uruchomieniowego ASP.NET. Przed wersją 7 serwera internetowego usług informacyjnych (IIS) firmy Microsoft istniała odrębna bariera między potokiem HTTP usług IIS a potokiem środowiska uruchomieniowego ASP.NET. Krótko mówiąc, w usługach IIS 6 i starszych program wykonuje tylko wtedy, FormsAuthenticationModule gdy żądanie jest delegowane z usług IIS do środowiska uruchomieniowego ASP.NET. Domyślnie usługi IIS przetwarzają zawartość statyczną — na przykład strony HTML i pliki CSS i obrazy — i wysyłają żądania tylko do środowiska uruchomieniowego ASP.NET, gdy strona z rozszerzeniem .aspx, asmx lub .ashx jest żądana.

Usługi IIS 7 umożliwiają jednak zintegrowane usługi IIS i potoki 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 adresów 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 przypadku usług IIS 7 można zintegrować moduł FormsAuthenticationModule i UrlAuthorizationModule z potokiem HTTP usług IIS, rozszerzając tym samym tę funkcję na wszystkie żądania.

Krok 1. Tworzenie witryny internetowej ASP.NET dla tej serii samouczków

Aby dotrzeć do najwięcej 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 microsoft SQL Server 2005 Express Edition. Jeśli używasz programu Visual Studio 2005 lub innej wersji programu Visual Studio 2008 lub SQL Server, nie martw się — kroki będą prawie identyczne, a wszelkie różnice nietrygalne zostaną wskazane.

Uwaga

Demonstracyjna aplikacja internetowa używana w każdym samouczku jest dostępna jako pobieranie. Ta aplikacja do pobrania została utworzona za pomocą programu Visual Web Developer 2008 przeznaczonego dla .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 trzeba jeszcze instalować platformy .NET 3.5 na komputerze, można pobrać aplikację internetową nie będzie działać bez uprzedniego usunięcia znaczników specyficznych dla wersji 3.5 z Web.config.

Zanim będziemy mogli skonfigurować uwierzytelnianie formularzy, najpierw potrzebujemy witryny internetowej ASP.NET. Zacznij od utworzenia nowej witryny internetowej opartej na systemie plików ASP.NET. 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, aby umieścić witrynę internetową, a następnie 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

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 krokami, które należy wykonać w porównaniu z wyświetlanymi zrzutami ekranu i instrukcjami podanymi w tych samouczkach.

Tworzenie nowego pliku System-Based witrynie sieci Web

Rysunek 2. Tworzenie nowego pliku System-Based witrynie sieci Web (kliknij, aby wyświetlić obraz pełnowymiarowy)

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.

Dodawanie strony wzorcowej o nazwie Site.master do witryny sieci Web

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 dla całej witryny w tym miejscu na stronie wzorcowej. Możesz użyć widoku Projekt i dodać dowolną potrzebną kontrolkę Układ lub Sieć Web albo ręcznie dodać znaczniki ręcznie 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 stylów z ustawieniami CSS zdefiniowanymi w pliku Style.css (który znajduje się w skojarzonym z tym samouczku pobieraniem). Chociaż nie można odróżnić od narzutu pokazanego poniżej, reguły CSS są zdefiniowane w taki sposób, że zawartość div> nawigacji <jest całkowicie umieszczona, tak aby pojawiała 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 regiony edytowalne zawartości są wskazywane przez kontrolkę ContentPlaceHolder , która może być widoczna w elemecie div> zawartości<. Nasza strona wzorcowa ma jeden ContentPlaceHolder element (MainContent), ale strony wzorcowej może mieć wiele symboli ContentPlaceHolder.

Po wprowadzeniu znaczników powyżej przełączenie do widoku Projekt 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.

Strona wzorcowa, po wyświetleniu w widoku projektu

Rysunek 4. Strona wzorcowa po wyświetleniu widoku projektu (kliknij, aby wyświetlić obraz pełnowymiarowy)

Tworzenie stron zawartości

W tym momencie 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. W związku z tym zacznij od usunięcia Default.aspx z projektu.

Następnie kliknij prawym przyciskiem myszy nazwę projektu w Eksplorator rozwiązań i wybierz dodanie nowego formularza sieci Web o nazwie Default.aspx. Tym razem zaznacz pole wyboru "Wybierz stronę wzorcową" i wybierz stronę wzorcową Site.master z listy.

Dodaj nową stronę Default.aspx, wybierając pozycję Wybierz stronę wzorcową

Rysunek 5. Dodawanie nowej strony Default.aspx Wybieranie strony wzorcowej (kliknij, aby wyświetlić obraz pełnowymiarowy)

Korzystanie ze strony wzorcowej Site.master

Rysunek 6. Używanie strony wzorcowej Site.master

Uwaga

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 internetowej". Po wybraniu opcji "Formularz zawartości internetowej" i kliknięciu przycisku Dodaj program Visual Studio wyświetli to samo okno dialogowe Wybieranie wzorca pokazane na rysunku 6.

Znacznik deklaratywny nowej strony Default.aspx zawiera tylko dyrektywę określającą @Page ścieżkę do pliku strony wzorcowej i kontrolkę Zawartość dla obiektu 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

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 pomocą <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 systemu Windows, odpowiedzialność serwera internetowego za uwierzytelnianie gościa jest zwykle wykonywana za pośrednictwem uwierzytelniania podstawowego, szyfrowego lub zintegrowanego systemu 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 Forms.

Jeśli projekt nie zawiera jeszcze pliku Web.config, dodaj go teraz, klikając prawym przyciskiem myszy nazwę projektu w Eksplorator rozwiązań, wybierając polecenie Dodaj nowy element, a następnie dodając plik konfiguracji sieci Web.

Jeśli projekt nie zawiera jeszcze Web.config, dodaj go teraz

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 korzystał z uwierzytelniania formularzy. Po tej zmianie znaczniki pliku Web.config powinny wyglądać podobnie do następujących:

<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

Ponieważ Web.config jest plikiem XML, wielkość liter jest ważna. Upewnij się, że ustawiono atrybut mode na Formularze ze znakiem "F". Jeśli używasz innej wielkości liter, takiej jak "formularze", podczas odwiedzania witryny za pośrednictwem przeglądarki wystąpi błąd konfiguracji.

Element <authentication> może opcjonalnie zawierać <forms> element podrzędny, który zawiera ustawienia specyficzne dla uwierzytelniania formularzy. Na razie użyjemy domyślnych ustawień uwierzytelniania formularzy. Bardziej szczegółowo omówimy <forms> element podrzędny 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 "Opis przepływu pracy uwierzytelniania formularzy" program automatycznie przekierowuje użytkownika do strony logowania, jeśli spróbuje uzyskać dostęp do strony, FormsAuthenticationModule 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 do użytkowników anonimowych. Dotyczy to pytania "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. Zobaczymy, jak to zrobić w kolejnym samouczku.

Strona logowania ma trzy obowiązki:

  1. Podaj interfejs, który umożliwia odwiedzającym wprowadzanie poświadczeń.
  2. Ustal, czy przesłane poświadczenia są prawidłowe.
  3. "Zaloguj się" użytkownik, tworząc bilet uwierzytelniania 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.

Dodawanie nowej strony ASP.NET o nazwie Login.aspx

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 w przypadku zaznaczenia utrwalonego wynikowego biletu uwierzytelniania w przeglądarce zostanie uruchomiony ponownie.

Dodaj dwie kontrolki TextBoxs do Login.aspx i ustaw ich ID właściwości odpowiednio na UserName i Password. Ustaw również właściwość Password na TextMode 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ę Sieć Web etykiet i ustaw jej ID właściwość na InvalidCredentialsMessage, jej Text właściwość na "Nazwa użytkownika lub hasło jest nieprawidłowe. Spróbuj ponownie.", jej ForeColor właściwość na Red, a jej Visible właściwość ma wartość 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>

Strona logowania zawiera dwa pola tekstowe: Pole wyboru, przycisk i etykietę

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 zdarzeń dla zdarzenia Click elementu LoginButton. W Projektant po prostu kliknij dwukrotnie kontrolkę Przycisk, aby utworzyć tę procedurę obsługi zdarzeń.

Określanie, czy podane poświadczenia są prawidłowe

Teraz musimy zaimplementować zadanie 2 w procedurze obsługi zdarzeń 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żytkownika, 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 magazynów użytkowników, jak i napisanie kodu w celu zweryfikowania podanych poświadczeń w magazynie. 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. W tej tabeli będzie wówczas 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ć obiektu SqlMembershipProvider, który używa bazy danych SQL Server dla magazynu użytkowników. W przypadku korzystania z obiektu SqlMembershipProvider musimy zaimplementować określony schemat bazy danych, który zawiera tabele, widoki i procedury składowane oczekiwane przez dostawcę. Sprawdzimy, jak zaimplementować ten schemat w samouczku Tworzenie schematu członkostwa w SQL Server. Po utworzeniu dostawcy członkostwa walidacja poświadczeń użytkownika jest tak prosta, jak wywoływanie metody ValidateUser(nazwa użytkownika, hasło)klasy Członkostwa, która zwraca wartość logiczną wskazującą, czy ważność nazwy użytkownika i hasła kombinacji. Ponieważ nie zaimplementowaliśmy jeszcze magazynu użytkowników sqlMembershipProvider, nie możemy w tej chwili użyć metody ValidateUser klasy Członkostwa.

Zamiast tworzyć własną niestandardową tabelę bazy danych Users (która byłaby przestarzała po zaimplementowaniu obiektu SqlMembershipProvider), zamiast tego zakodujemy prawidłowe poświadczenia na samej stronie logowania. W procedurze obsługi zdarzeń Click elementu LoginButton dodaj następujący 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 — i wszystkie trzy mają to samo hasło ("hasło"). Kod przechodzi przez tablice użytkowników i haseł, które szukają prawidłowej nazwy użytkownika i hasła. Jeśli nazwa użytkownika i hasło są prawidłowe, musimy zalogować się do użytkownika, a następnie przekierować je do odpowiedniej strony. Jeśli poświadczenia są nieprawidłowe, zostanie wyświetlona etykieta InvalidCredentialsMessage.

Gdy użytkownik wprowadza prawidłowe poświadczenia, wspomniałem, że są one następnie przekierowywane 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 je do:

Login.aspx? ReturnUrl=ProtectedPage.aspx

Po pomyślnym zalogowaniu użytkownik powinien zostać przekierowany z powrotem do ProtectedPage.aspx. Alternatywnie użytkownicy mogą odwiedzić stronę logowania na własnej woli. W takim przypadku po zalogowaniu użytkownika należy wysłać go 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, a tym samym zalogować użytkownika do witryny. 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ż istnieje kilka metod w klasie FormsAuthentication, trzy interesujące nas w tym momencie są następujące:

  • 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) w celu wygenerowania pliku cookie uwierzytelniania formularzy. Ta metoda dodaje następnie plik cookie zwrócony przez metodę GetAuthCookie do kolekcji Cookie (przy założeniu, że jest używane uwierzytelnianie formularzy opartych na plikach cookie; w przeciwnym razie ta metoda wywołuje klasę wewnętrzną, która obsługuje logikę biletu 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 przydatny, gdy musisz zmodyfikować bilet uwierzytelniania przed zapisaniem pliku cookie w kolekcji Cookies. ZestawAuthCookie jest przydatny, jeśli chcesz utworzyć bilet uwierzytelniania formularzy i dodać go do kolekcji Pliki cookie, 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ć się do użytkownika i przekierować je do odpowiedniej strony, użyjmy polecenia 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.Check);

Podczas tworzenia biletu uwierzytelniania formularzy używamy właściwości TextBox UserName dla parametru nazwy użytkownika biletu uwierzytelniania formularzy oraz stanu checkbox RememberMe dla 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 "źle". Po kliknięciu przycisku Zaloguj nastąpi powrót i zostanie wyświetlona etykieta InvalidCredentialsMessage.

Etykieta InvalidCredentialsMessage jest wyświetlana podczas wprowadzania nieprawidłowych poświadczeń

Rysunek 10. Etykieta InvalidCredentialsMessage jest wyświetlana podczas wprowadzania nieprawidłowych poświadczeń (kliknij, aby wyświetlić obraz pełnowymiarowy)

Następnie wprowadź prawidłowe poświadczenia i kliknij przycisk Zaloguj. Tym razem, gdy nastąpi powrót, zostanie utworzony bilet uwierzytelniania formularzy i nastąpi automatyczne przekierowanie 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 sprawdza techniki rejestrowania użytkownika z witryny internetowej.

Zabezpieczanie strony logowania

Gdy użytkownik wprowadza swoje poświadczenia i przesyła formularz strony logowania, poświadczenia — w tym 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, należy zaszyfrować ruch sieciowy przy użyciu protokołu Secure Socket Layer (SSL). Zapewni to szyfrowanie poświadczeń (a także znaczników HTML całej strony) od momentu opuszczenia przeglądarki do momentu odebrania ich przez serwer internetowy.

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 w przeciwnym razie zostanie wysłane za pośrednictwem przewodu w postaci zwykłego tekstu. Nie musisz martwić się o zabezpieczenie biletu uwierzytelniania formularzy, ponieważ domyślnie jest szyfrowany i podpisany cyfrowo (aby zapobiec manipulacji). Bardziej szczegółowe omówienie zabezpieczeń biletów uwierzytelniania formularzy przedstawiono w poniższym samouczku.

Uwaga

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 tożsamości

W tym momencie włączyliśmy uwierzytelnianie formularzy i utworzyliśmy podstawową stronę logowania, ale musimy jeszcze sprawdzić, w jaki sposób możemy 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 dwa kontrolki Panel, jeden o nazwie AuthenticatedMessagePanel i inny 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 "Log In" i jej właściwość NavigateUrl na "~/Login.aspx". W tym momencie deklaratywne znaczniki 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 prawdopodobnie się domyśliłeś, oto pomysł, aby wyświetlić tylko UwierzytelnionyMessagePanel do uwierzytelnionych odwiedzających i tylko AnonymousMessagePanel do 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ź stronę Default.aspx za pośrednictwem przeglądarki. Zakładając, że jeszcze się zalogować, zostanie wyświetlony 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 strona wyświetla komunikat "Witamy ponownie!" (patrz Rysunek 12).

Podczas odwiedzania anonimowo zostanie wyświetlony link logowania

Rysunek 11. Podczas odwiedzania anonimowo jest wyświetlany link logowania

Uwierzytelnieni użytkownicy są wyświetlani

Rysunek 12. Uwierzytelnieni użytkownicy są wyświetlani "Witamy ponownie!" Komunikat

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 dwa elementy członkowskie:

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 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 formularzy. Oprócz tych trzech właściwości, FormsIdentity obejmuje dostęp do bazowego biletu uwierzytelniania za pośrednictwem jego 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żnym punktem, który należy zabrać tutaj, jest to, że parametr nazwy użytkownika określony w metodzie FormsAuthentication.GetAuthCookie(username, persistCookie), FormsAuthentication.SetAuthCookie(username, persistCookie) i FormsAuthentication.RedirectFromLoginPage(nazwa użytkownika, persistCookie) jest tą samą wartością zwracaną przez User.Identity.Name. Ponadto bilet uwierzytelniania utworzony za pomocą tych metod 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;

Przekażmy bardziej spersonalizowaną wiadomość w Default.aspx. Zaktualizuj procedurę obsługi zdarzeń Page_Load, aby właściwość Text etykiety WelcomeBackMessage została przypisana do ciągu "Witamy wstecz, nazwa użytkownika!"

WelcomeBackMessage.Text = "Witamy z powrotem, " + User.Identity.Name + "!";

Rysunek 13 przedstawia efekt tej modyfikacji (podczas logowania się jako użytkownik Scott).

Komunikat powitalny zawiera aktualnie zalogowaną nazwę użytkownika

Rysunek 13. Wiadomość powitalna zawiera aktualnie zalogowaną nazwę 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 — wszystkie znaczniki dodane do tego szablonu są wyświetlane tylko anonimowym odwiedzającym.
  • LoggedInTemplate — znaczniki tego szablonu są wyświetlane tylko dla uwierzytelnionych użytkowników.

Dodajmy kontrolkę LoginView do strony wzorcowej witryny Site.master. Zamiast dodawać tylko kontrolkę LoginView, dodajmy jednak zarówno nową kontrolkę ContentPlaceHolder, jak i kontrolkę LoginView w ramach tej nowej kontrolki ContentPlaceHolder. Uzasadnienie tej decyzji stanie się widoczne wkrótce.

Uwaga

Oprócz kontrolek AnonymousTemplate i LoggedInTemplate kontrolka LoginView może zawierać szablony specyficzne dla ról. Szablony specyficzne dla ról pokazują znaczniki tylko dla tych użytkowników, którzy należą do określonej roli. W przyszłym samouczku przyjrzymy się funkcjom opartym na rolach kontrolki LoginView.

Zacznij od dodania symbolu ContentPlaceHolder o nazwie LoginContent do strony wzorcowej w elemencie div> nawigacji<. Możesz po prostu przeciągnąć kontrolkę ContentPlaceHolder z przybornika do widoku Źródło, umieszczając wynikowy znacznik tuż nad menu "TODO: Menu trafi tutaj..." Tekst.

<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 zawartość domyślną dla elementu ContentPlaceHolder. Oznacza to, że ASP.NET strony korzystające z tej strony wzorcowej mogą określić własną zawartość dla każdego elementu ContentPlaceHolder lub użyć domyślnej zawartości strony wzorcowej.

Kontrolki LoginView i inne kontrolki związane z logowaniem znajdują się na karcie Logowanie przybornika.

Kontrolka LoginView w przyborniku

Rysunek 14. Kontrolka LoginView w przyborniku

Następnie dodaj dwa <elementy br/> bezpośrednio po kontrolce LoginView, ale nadal w elemecie ContentPlaceHolder. Na tym etapie znaczniki elementu div> nawigacji <powinny 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 elementu LoginView można zdefiniować na podstawie Projektant lub narzutu deklaratywnego. W Projektant programu Visual Studio rozwiń tag inteligentny LoginView, który zawiera listę skonfigurowanych szablonów na liście rozwijanej. 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 "Witaj ponownie". Następnie przeciągnij kontrolkę LoginName z przybornika do elementu LoggedInTemplate, umieszczając ją bezpośrednio po tekście "Witaj ponownie". Kontrolka LoginName, jak wskazuje jej nazwa, wyświetla nazwę aktualnie zalogowanego użytkownika. Wewnętrznie kontrolka LoginName po prostu zwraca właściwość User.Identity.Name

Po dodaniu tych dodatków do szablonów kontrolki LoginView znacznik powinien wyglądać podobnie do następującego:

<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 po odwiedzeniu 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 pośrednictwem właśnie dodanej kontrolki LoginView) i raz w obszarze zawartości Default.aspx (za pomocą kontrolek Panelu i logiki programowej).

Zostanie wyświetlona kontrolka LoginView

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ę nie na miejscu. Ponieważ kontrolka LoginView została umieszczona w elemecie ContentPlaceHolder na stronie wzorcowej, możemy zastąpić ten domyślny znacznik na naszej stronie zawartości. Otwórz Login.aspx i przejdź do Projektant. 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 Projektant — w kontrolce LoginContent ContentPlaceHolder jest wyświetlana domyślna adiustacja (kontrolka LoginView).

Na stronie logowania jest wyświetlana domyślna zawartość identyfikatora logowania strony wzorcowejContent ContentPlaceHolder

Rysunek 16. Na stronie logowania jest wyświetlana domyślna zawartość elementu LoginContent ContentPlaceHolder strony wzorcowej (kliknij, aby wyświetlić obraz pełnowymiarowy)

Aby zastąpić domyślny znacznik loginContent ContentPlaceHolder, po prostu kliknij prawym przyciskiem myszy region w Projektant i wybierz opcję Utwórz zawartość niestandardową z menu kontekstowego. (W przypadku korzystania z programu Visual Studio 2008 element ContentPlaceHolder zawiera tag inteligentny, który po wybraniu oferuje tę samą opcję). Spowoduje to dodanie nowej kontrolki Zawartość do znaczników strony, a tym samym umożliwia zdefiniowanie zawartości niestandardowej dla tej strony. W tym miejscu możesz dodać niestandardowy komunikat, taki jak "Zaloguj się...", ale pozostawmy to pole puste.

Uwaga

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 zawartości niestandardowej 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 po odwiedzeniu w przeglądarce po wprowadzeniu tej zmiany. Należy pamiętać, że podczas wizyty w Default.aspx nie ma komunikatu "Hello, stranger" lub "Welcome back, username" (<>Witaj, nieznajomy lub "Witaj, nazwa użytkownika".

Strona logowania ukrywa domyślne znaczniki LoginContent ContentPlaceHolder

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 zarejestrowania użytkownika w witrynie, ale nie zobaczyliśmy jeszcze, jak zalogować użytkownika. Oprócz metod rejestrowania użytkownika w programie 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 wylogowania jest tak powszechną funkcją, która ASP.NET zawiera kontrolkę przeznaczoną specjalnie do rejestrowania użytkownika. Kontrolka LoginStatus wyświetla przycisk LinkButton "Login" lub "Logout" LinkButton w zależności od stanu uwierzytelniania użytkownika. Element LinkButton "Login" jest renderowany dla użytkowników anonimowych, natomiast element LinkButton "Logout" jest wyświetlany dla uwierzytelnionych użytkowników. Tekst dla atrybutów LinkButtons "Login" i "Logout" można skonfigurować za pomocą właściwości LoginText i LogoutText klasy LoginStatus.

Kliknięcie linku "Login" powoduje powrót, z którego zostanie wystawione przekierowanie do strony logowania. Kliknięcie kontrolki "Logout" LinkButton powoduje wywołanie metody FormsAuthentication.SignOff przez kontrolkę LoginStatus, a następnie przekierowanie użytkownika do strony. Strona, do której jest przekierowywany zalogowany użytkownik, 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 na stronę, 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.

Być może zastanawiasz się, dlaczego przekierowanie jest wykonywane tutaj. Jeśli użytkownik chce pozostać na tej samej stronie, dlaczego potrzeba jawnego przekierowania? Przyczyną jest to, że po kliknięciu linku "Logoff" użytkownik nadal ma bilet uwierzytelniania formularzy w kolekcji plików cookie. W związku z tym żądanie ogłaszania zwrotnego jest uwierzytelnionymi żądaniami. 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ę. Po ponownym żądaniu strony przez przeglądarkę bilet uwierzytelniania formularzy został usunięty i dlatego żą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 w celu wysłania użytkownika do strony z komunikatem potwierdzającym, że użytkownik został wylogowany. 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 z wyjaśnieniem 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 "Login" lub "Logout" LinkButton. Po dodaniu kontrolki LoginStatus hiperlink "Zaloguj się" w elemecie AnonymousTemplate jest nadmiarowy, więc usuń go.

Rysunek 18 przedstawia Default.aspx podczas wizyty Jisun. Zwróć uwagę, że w lewej kolumnie jest wyświetlany komunikat "Witaj ponownie, Jisun" wraz z linkiem umożliwiającym wylogowanie się. Kliknięcie wylogowania LinkButton powoduje ogłaszanie zwrotne, znaki Jisun z systemu, a następnie przekierowuje ją do Logout.aspx. Jak pokazano na rysunku 19, do czasu, gdy Jisun osiągnie Logout.aspx została już wylogowana i dlatego jest anonimowa. W związku z tym lewa kolumna zawiera tekst "Witaj, obcy" i link do strony logowania.

pokazuje Default.aspx

Rysunek 18. Default.aspx pokazuje tekst "Welcome Back, Jisun" wraz z elementem LinkButton "Logout" (Kliknij, aby wyświetlić obraz w pełnym rozmiarze)

pokazy Logout.aspx

Rysunek 19. Logout.aspx Pokazuje "Welcome, stranger" wraz z "Login" LinkButton (Kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Uwaga

Zachęcam do dostosowania strony Logout.aspx w celu ukrycia elementu LoginContent ContentPlaceHolder strony wzorcowej (tak jak w przypadku Login.aspx w kroku 4). Przyczyną jest to, że element LinkButton "Login" renderowany przez kontrolkę LoginStatus (pod kontrolką "Hello, stranger") wysyła użytkownika do strony logowania przekazującej bieżący adres URL w parametrze querystring ReturnUrl. Krótko mówiąc, jeśli użytkownik, który wylogował, kliknie ten identyfikator "LoginStatus" LinkButton, a następnie zaloguje się, zostanie przekierowany z powrotem do 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 implementacji 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 .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 LogowaniaView, 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 przeanalizowane w przyszłych samouczkach.

W tym samouczku przedstawiono pobiedne omówienie uwierzytelniania formularzy. Nie zbadaliśmy różnych opcji konfiguracji, przyjrzeliśmy się, jak działają bilety uwierzytelniania formularzy bez plików cookie lub dowiesz się, jak ASP.NET chroni zawartość biletu uwierzytelniania formularzy.

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:

Szkolenia 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 do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.

Specjalne podziękowania...

Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Głównym recenzentem tego samouczka była ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Recenzenci z tego samouczka to Alicja Maziarz, John Suru i Teresa Murphy. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresemmitchell@4GuysFromRolla.com .