Udostępnij za pośrednictwem


Walidacja poświadczeń użytkownika względem magazynu użytkowników członkostwa (VB)

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 sprawdzimy, jak zweryfikować poświadczenia użytkownika w magazynie użytkowników członkostwa przy użyciu zarówno środków programowych, jak i kontrolki Logowania. Przyjrzymy się również sposobom dostosowywania wyglądu i zachowania kontrolki logowania.

Wprowadzenie

W poprzednim samouczku przyjrzeliśmy się, jak utworzyć nowe konto użytkownika w strukturze członkostwa. Najpierw przyjrzeliśmy się programowe tworzeniu kont użytkowników za pomocą Membership metody klasy CreateUser , a następnie zbadaliśmy przy użyciu kontrolki CreateUserWizard Web. Jednak strona logowania obecnie weryfikuje podane poświadczenia względem trwale zakodowanej listy par nazwy użytkownika i hasła. Musimy zaktualizować logikę strony logowania, aby zweryfikować poświadczenia względem magazynu użytkowników platformy członkostwa.

Podobnie jak w przypadku tworzenia kont użytkowników, poświadczenia można zweryfikować programowo lub deklaratywnie. Interfejs API członkostwa zawiera metodę programowego weryfikowania poświadczeń użytkownika w magazynie użytkowników. A ASP.NET jest dostarczany z kontrolką Logowania w sieci Web, która renderuje interfejs użytkownika z polami tekstowymi dla nazwy użytkownika i hasła oraz przycisku w celu zalogowania się.

W tym samouczku sprawdzimy, jak zweryfikować poświadczenia użytkownika w magazynie użytkowników członkostwa przy użyciu zarówno środków programowych, jak i kontrolki Logowania. Przyjrzymy się również sposobom dostosowywania wyglądu i zachowania kontrolki logowania. Zaczynamy!

Krok 1. Weryfikowanie poświadczeń względem magazynu użytkowników członkostwa

W przypadku witryn internetowych korzystających z uwierzytelniania formularzy użytkownik loguje się do witryny internetowej, odwiedzając stronę logowania i wprowadzając swoje poświadczenia. Te poświadczenia są następnie porównywane z magazynem użytkowników. Jeśli są one prawidłowe, użytkownik otrzymuje bilet uwierzytelniania formularzy, który jest tokenem zabezpieczającym wskazującym tożsamość i autentyczność osoby odwiedzającej.

Aby zweryfikować użytkownika względem struktury członkostwa, użyj Membership metody klasy ValidateUser. Metoda ValidateUser przyjmuje dwa parametry wejściowe — username i password — i zwraca wartość logiczną wskazującą, czy poświadczenia były prawidłowe. Podobnie jak w przypadku metody badanej CreateUser w poprzednim samouczku ValidateUser metoda deleguje rzeczywistą walidację do skonfigurowanego dostawcy członkostwa.

Element SqlMembershipProvider weryfikuje podane poświadczenia, uzyskując hasło określonego użytkownika za pośrednictwem aspnet_Membership_GetPasswordWithFormat procedury składowanej. Pamiętaj, że SqlMembershipProvider hasła użytkowników są przechowywane w jednym z trzech formatów: wyczyść, zaszyfrowane lub skróty. Procedura aspnet_Membership_GetPasswordWithFormat składowana zwraca hasło w formacie nieprzetworzonym. W przypadku zaszyfrowanych lub skrótów SqlMembershipProvider haseł przekształca password wartość przekazaną do metody w ValidateUser odpowiedni stan zaszyfrowany lub skrót, a następnie porównuje je z wartością zwróconą z bazy danych. Jeśli hasło przechowywane w bazie danych pasuje do sformatowanego hasła wprowadzonego przez użytkownika, poświadczenia są prawidłowe.

Zaktualizujmy naszą stronę logowania (~/Login.aspx), aby zweryfikować podane poświadczenia względem magazynu użytkowników platformy członkostwa. Utworzyliśmy tę stronę logowania z powrotem w samouczku Omówienie uwierzytelniania formularzy, tworząc interfejs z dwoma polami TextBoxes dla nazwy użytkownika i hasła, pole wyboru Zapamiętaj mnie i przycisk Logowania (zobacz Rysunek 1). Kod weryfikuje wprowadzone poświadczenia względem trwale zakodowanej listy par nazwy użytkownika i hasła (Scott/password, Jisun/password i Sam/password).

Interfejs strony logowania zawiera dwa pola tekstowe, CheckBoxList i przycisk

Rysunek 1. Interfejs strony logowania zawiera dwa pola tekstowe, CheckBoxList i przycisk (kliknij, aby wyświetlić obraz pełnowymiarowy)

Interfejs użytkownika strony logowania może pozostać niezmieniony, ale musimy zastąpić procedurę obsługi zdarzeń przycisku Click Logowania kodem, który weryfikuje użytkownika w magazynie użytkowników platformy członkostwa. Zaktualizuj procedurę obsługi zdarzeń, aby jego kod był wyświetlany w następujący sposób:

Protected Sub LoginButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LoginButton.Click

 ' Validate the user against the Membership framework user store
 If Membership.ValidateUser(UserName.Text, Password.Text) Then
 ' Log the user into the site
 FormsAuthentication.RedirectFromLoginPage(UserName.Text, RememberMe.Checked)
 End If
    
 ' If we reach here, the user's credentials were invalid
 InvalidCredentialsMessage.Visible = True
End Sub

Ten kod jest niezwykle prosty. Zaczynamy od wywołania Membership.ValidateUser metody , przekazując dostarczoną nazwę użytkownika i hasło. Jeśli ta metoda zwróci wartość True, użytkownik jest zalogowany do witryny za pośrednictwem FormsAuthentication metody RedirectFromLoginPage klasy. (Jak omówiono w dokumencie Samouczek Omówienie uwierzytelniania formularzy , który FormsAuthentication.RedirectFromLoginPage tworzy bilet uwierzytelniania formularzy, a następnie przekierowuje użytkownika do odpowiedniej strony). Jeśli jednak poświadczenia są nieprawidłowe, InvalidCredentialsMessage zostanie wyświetlona etykieta, informując użytkownika o nieprawidłowej nazwie użytkownika lub haśle.

To wszystko!

Aby przetestować, czy strona logowania działa zgodnie z oczekiwaniami, spróbuj zalogować się przy użyciu jednego z kont użytkowników utworzonych w poprzednim samouczku. Jeśli nie utworzono jeszcze konta, utwórz je z ~/Membership/CreatingUserAccounts.aspx poziomu strony.

Uwaga

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.

Jak struktura członkostwa obsługuje nieprawidłowe próby logowania

Gdy użytkownik osiągnie stronę logowania i prześle swoje poświadczenia, przeglądarka wysyła żądanie HTTP do strony logowania. Jeśli poświadczenia są prawidłowe, odpowiedź HTTP zawiera bilet uwierzytelniania w pliku cookie. W związku z tym haker próbujący włamać się do witryny może utworzyć program, który wyczerpująco wysyła żądania HTTP do strony logowania z prawidłową nazwą użytkownika i odgadnięciem hasła. Jeśli hasło jest poprawne, strona logowania zwróci plik cookie biletu uwierzytelniania, w którym program wie, że natknął się na prawidłową parę nazwy użytkownika/hasła. Poprzez siłę, taki program może być w stanie natknąć się na hasło użytkownika, zwłaszcza jeśli hasło jest słabe.

Aby zapobiec takim atakom siłowym, struktura członkostwa blokuje użytkownika, jeśli w określonym przedziale czasu istnieje pewna liczba nieudanych prób logowania. Dokładne parametry można konfigurować za pomocą następujących dwóch ustawień konfiguracji dostawcy członkostwa:

  • maxInvalidPasswordAttempts — określa, ile nieprawidłowych prób hasła jest dozwolonych dla użytkownika w przedziale czasu przed zablokowaniem konta. Wartość domyślna to 5.
  • passwordAttemptWindow — wskazuje okres w minutach, w których określona liczba nieprawidłowych prób logowania spowoduje zablokowanie konta. Wartość domyślna to 10.

Jeśli użytkownik został zablokowany, nie może zalogować się, dopóki administrator nie odblokuje swojego konta. Gdy użytkownik zostanie zablokowany, ValidateUser metoda zawsze zwróci Falsewartość , nawet jeśli podano prawidłowe poświadczenia. Chociaż to zachowanie zmniejsza prawdopodobieństwo, że haker włamie się do witryny poprzez metody siłowe, może to spowodować zablokowanie prawidłowego użytkownika, który po prostu zapomniał hasła lub przypadkowo ma blokadę Caps Lock lub ma zły dzień pisania.

Niestety nie ma wbudowanego narzędzia do odblokowywania konta użytkownika. Aby odblokować konto, możesz bezpośrednio zmodyfikować bazę danych — zmienić IsLockedOut pole w aspnet_Membership tabeli dla odpowiedniego konta użytkownika — lub utworzyć interfejs internetowy, który wyświetla listę zablokowanych kont z opcjami ich odblokowania. Przeanalizujemy tworzenie interfejsów administracyjnych na potrzeby wykonywania typowych zadań związanych z kontem użytkownika i rolami w przyszłym samouczku.

Uwaga

Jedną z wad ValidateUser metody jest to, że gdy podane poświadczenia są nieprawidłowe, nie podaje żadnego wyjaśnienia, dlaczego. Poświadczenia mogą być nieprawidłowe, ponieważ nie ma pasującej pary nazwy użytkownika/hasła w magazynie użytkowników lub dlatego, że użytkownik nie został jeszcze zatwierdzony lub ponieważ użytkownik został zablokowany. W kroku 4 zobaczymy, jak wyświetlić użytkownikowi bardziej szczegółowy komunikat, gdy próba logowania zakończy się niepowodzeniem.

Krok 2. Zbieranie poświadczeń za pomocą kontrolki internetowej logowania

Kontrolka Login Web renderuje domyślny interfejs użytkownika bardzo podobny do interfejsu utworzonego z powrotem w samouczku Omówienie uwierzytelniania formularzy. Użycie kontrolki Logowania pozwala nam na utworzenie interfejsu w celu zbierania poświadczeń gościa. Ponadto kontrolka Logowania automatycznie loguje się do użytkownika (przy założeniu, że przesłane poświadczenia są prawidłowe), co pozwala zaoszczędzić nam konieczność pisania dowolnego kodu.

Zaktualizujmy Login.aspxelement , zastępując ręcznie utworzony interfejs i kod kontrolką Login. Zacznij od usunięcia istniejącego znaczników i kodu w pliku Login.aspx. Możesz go usunąć wprost lub po prostu skomentować. Aby oznaczyć znaczniki deklaratywne jako komentarz, umieść je z ogranicznikami <%-- i --%> . Możesz wprowadzić te ograniczniki ręcznie lub, jak pokazano na rysunku 2, możesz wybrać tekst do komentarza, a następnie kliknąć ikonę Komentarz zaznaczonych wierszy na pasku narzędzi. Podobnie możesz użyć ikony Komentarz zaznaczonych wierszy, aby oznaczyć wybrany kod w klasie za kodem.

Oznacz jako komentarz istniejący deklaratywny znacznik i kod źródłowy w pliku Login.aspx

Rysunek 2. Oznacz istniejące znaczniki deklaratywne i kod źródłowy w pliku Login.aspx (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Ikona Komentarz zaznaczonych wierszy nie jest dostępna podczas wyświetlania znaczników deklaratywnych w programie Visual Studio 2005. Jeśli nie używasz programu Visual Studio 2008, musisz ręcznie dodać <%-- ograniczniki i --%> .

Następnie przeciągnij kontrolkę Login z przybornika na stronę i ustaw jej ID właściwość na myLogin. Na tym etapie ekran powinien wyglądać podobnie do rysunku 3. Należy pamiętać, że domyślny interfejs kontrolki Login zawiera kontrolki TextBox dla nazwy użytkownika i hasła, zapamiętaj mnie przy następnym checkboxie i przycisk logowania. Istnieją również RequiredFieldValidator kontrolki dla dwóch pola TextBoxes.

Dodawanie kontrolki logowania do strony

Rysunek 3. Dodawanie kontrolki logowania do strony (kliknij, aby wyświetlić obraz pełnowymiarowy)

I gotowe! Po kliknięciu przycisku Zaloguj się kontrolki Logowania nastąpi powrót, a kontrolka Login wywoła metodę Membership.ValidateUser , przekazując wprowadzoną nazwę użytkownika i hasło. Jeśli poświadczenia są nieprawidłowe, kontrolka Logowania wyświetla komunikat informujący o tym. Jeśli jednak poświadczenia są prawidłowe, kontrolka Logowanie tworzy bilet uwierzytelniania formularzy i przekierowuje użytkownika do odpowiedniej strony.

Kontrolka Logowanie używa czterech czynników w celu określenia odpowiedniej strony w celu przekierowania użytkownika do po pomyślnym zalogowaniu:

  • Czy kontrolka Logowania znajduje się na stronie logowania zgodnie z definicją, ustawiając loginUrl w konfiguracji uwierzytelniania formularzy; wartość domyślna tego ustawienia to Login.aspx
  • Obecność parametru ReturnUrl ciągu zapytania
  • Wartość właściwości kontrolki DestinationUrl Login
  • Wartość określona defaultUrl w ustawieniach konfiguracji uwierzytelniania formularzy; wartość domyślna tego ustawienia to Default.aspx

Rysunek 4 przedstawia sposób, w jaki kontrolka Logowania używa tych czterech parametrów, aby uzyskać odpowiednią decyzję o stronie.

Kontrolka Logowania używa czterech parametrów do podjęcia odpowiedniej decyzji o stronie.

Rysunek 4. Dodawanie kontrolki logowania do strony (kliknij, aby wyświetlić obraz pełnowymiarowy)

Poświęć chwilę na przetestowanie kontrolki Logowania, odwiedzając witrynę za pośrednictwem przeglądarki i logując się jako istniejący użytkownik w strukturze członkostwa.

Renderowany interfejs kontrolki Logowania jest wysoce konfigurowalny. Istnieje wiele właściwości, które wpływają na jej wygląd; Co więcej, kontrolkę Login można przekonwertować na szablon, aby uzyskać dokładną kontrolę nad układem elementów interfejsu użytkownika. Pozostała część tego kroku sprawdza, jak dostosować wygląd i układ.

Dostosowywanie wyglądu kontrolki logowania

Domyślne ustawienia właściwości kontrolki Logowania renderują interfejs użytkownika z tytułem (Log In), kontrolkami TextBox i Label dla danych wejściowych nazwy użytkownika i hasła, pamiętaj mnie przy następnym checkboxie i przycisku Zaloguj. Wygląd tych elementów można konfigurować za pomocą wielu właściwości kontrolki Logowania. Ponadto dodatkowe elementy interfejsu użytkownika — takie jak link do strony w celu utworzenia nowego konta użytkownika — można dodać, ustawiając właściwość lub dwie.

Poświęćmy chwilę, aby rozgniecić wygląd kontrolki Logowania. Login.aspx Ponieważ strona ma już tekst w górnej części strony z napisem Login, tytuł kontrolki Logowania jest zbędny. W związku z TitleText tym wyczyść wartość właściwości, aby usunąć tytuł kontrolki Logowania.

Nazwa użytkownika: i Hasło: etykiety po lewej stronie dwóch kontrolek TextBox można dostosować odpowiednio za pomocą UserNameLabelText właściwości iPasswordLabelText. Zmieńmy nazwę użytkownika: etykietę, aby odczytać nazwę użytkownika:. Style Label i TextBox można konfigurować odpowiednio za pomocą LabelStyle właściwości iTextBoxStyle.

Właściwość Zapamiętuj mnie przy następnym ustawieniu właściwości Text kontrolki Login za pomocą kontrolki RememberMeTextCheckBox i jej domyślnym stanem sprawdzania można skonfigurować za pośrednictwem RememberMeSet właściwości (która jest domyślnie równa False). Przejdź dalej i ustaw RememberMeSet właściwość na True, aby zapamiętać mnie przy następnym zaznaczeniu Pola wyboru domyślnie.

Kontrolka Login oferuje dwie właściwości do dostosowywania układu kontrolek interfejsu użytkownika. Właściwość TextLayout wskazuje , czy nazwa użytkownika: i hasło: etykiety są wyświetlane po lewej stronie odpowiednich pól tekstowych (wartość domyślna) lub powyżej nich. WłaściwośćOrientation wskazuje, czy dane wejściowe nazwy użytkownika i hasła znajdują się w pionie (jeden powyżej drugiego) lub poziomo. Pozostawię te dwie właściwości ustawione na ich wartości domyślne, ale zachęcam do wypróbowania ustawienia tych dwóch właściwości na ich wartości inne niż domyślne, aby zobaczyć wynikowy efekt.

Uwaga

W następnej sekcji Konfigurowanie układu kontrolki logowania przyjrzymy się użyciu szablonów do zdefiniowania dokładnego układu elementów interfejsu użytkownika kontrolki Układ.

Podsumuj ustawienia właściwości kontrolki Logowania, ustawiając CreateUserText właściwości i CreateUserUrl na Niezarejestrowane jeszcze? Utwórz konto! i ~/Membership/CreatingUserAccounts.aspx, odpowiednio. Spowoduje to dodanie hiperlinku do interfejsu kontrolki Logowania wskazującego stronę utworzoną w poprzednim samouczku. Właściwości i HelpPageUrlPasswordRecoveryTextPasswordRecoveryUrl właściwości kontrolki HelpPageText Logowania działają w taki sam sposób, renderowanie linków do strony pomocy i strony odzyskiwania hasła.

Po wprowadzeniu tych zmian właściwości znaczniki deklaratywne i wygląd kontrolki logowania powinny wyglądać podobnie do przedstawionego na rysunku 5.

Wartości właściwości kontrolki logowania dyktują jego wygląd

Rysunek 5. Wartości właściwości kontrolki logowania dyktują jego wygląd (kliknij, aby wyświetlić obraz pełnowymiarowy)

Konfigurowanie układu kontrolki logowania

Domyślny interfejs użytkownika kontrolki Login Web określa interfejs w kodzie HTML <table>. Ale co zrobić, jeśli potrzebujemy bardziej precyzyjnej kontroli nad renderowanych danych wyjściowych? Może chcemy zastąpić <table> ciąg serią tagów <div> . A co zrobić, jeśli nasza aplikacja wymaga dodatkowych poświadczeń do uwierzytelniania? Wiele witryn finansowych, na przykład, wymaga od użytkowników podania nie tylko nazwy użytkownika i hasła, ale także osobistego numeru identyfikacyjnego (PIN) lub innych informacji identyfikujących. Niezależnie od przyczyn, można przekonwertować kontrolkę Logowania na szablon, z którego można jawnie zdefiniować deklaratywny znacznik interfejsu.

Aby zaktualizować kontrolkę Logowania, musimy wykonać dwie czynności, aby zebrać dodatkowe poświadczenia:

  1. Zaktualizuj interfejs kontrolki Logowania, aby uwzględnić kontrolki sieci Web w celu zbierania dodatkowych poświadczeń.
  2. Zastąp wewnętrzną logikę uwierzytelniania kontrolki Logowania, aby użytkownik był uwierzytelniany tylko wtedy, gdy jego nazwa użytkownika i hasło są prawidłowe, a ich dodatkowe poświadczenia są również prawidłowe.

Aby wykonać pierwsze zadanie, musimy przekonwertować kontrolkę Login na szablon i dodać niezbędne kontrolki sieci Web. Jeśli chodzi o drugie zadanie, logika uwierzytelniania kontrolki Logowania może zostać zastąpiona przez utworzenie procedury obsługi zdarzeń dla zdarzenia kontrolkiAuthenticate.

Zaktualizujmy kontrolkę Logowanie, tak aby monitowały użytkowników o podanie nazwy użytkownika, hasła i adresu e-mail oraz uwierzytelnienia użytkownika tylko wtedy, gdy podany adres e-mail jest zgodny z adresem e-mail podanym w pliku. Najpierw musimy przekonwertować interfejs kontrolki Logowania na szablon. Z poziomu tagu inteligentnego kontrolki Logowania wybierz opcję Konwertuj na szablon.

Konwertowanie kontrolki logowania na szablon

Rysunek 6. Konwertowanie kontrolki logowania na szablon (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Aby przywrócić kontrolkę Login do jej wersji przed szablonem, kliknij link Resetuj z tagu inteligentnego kontrolki.

Konwertowanie kontrolki Login na szablon powoduje dodanie LayoutTemplate znacznika deklaratywnego kontrolki z elementami HTML i kontrolkami sieci Web definiującymi interfejs użytkownika. Jak pokazano na rysunku 7, konwertowanie kontrolki na szablon spowoduje usunięcie wielu właściwości z okno Właściwości, takich jak TitleText, CreateUserUrli tak dalej, ponieważ te wartości właściwości są ignorowane podczas korzystania z szablonu.

Mniej właściwości jest dostępnych, gdy kontrolka logowania jest konwertowana na szablon

Rysunek 7. Mniejsza liczba właściwości jest dostępna po przekonwertowaniu kontrolki logowania na szablon (kliknij, aby wyświetlić obraz pełnowymiarowy)

Znaczniki HTML w elemecie LayoutTemplate mogą być modyfikowane zgodnie z potrzebami. Podobnie możesz dodawać nowe kontrolki sieci Web do szablonu. Jednak ważne jest, aby podstawowe kontrolki sieci Web kontrolki logowania pozostały w szablonie i zachowały przypisane ID wartości. W szczególności nie usuwaj ani nie zmieniaj nazwy UserName pola tekstowegoRememberMe, Password pola wyboru, przycisku, LoginButtonFailureText etykiety ani RequiredFieldValidator kontrolek.

Aby zebrać adres e-mail osoby odwiedzającej, musimy dodać pole tekstowe do szablonu. Dodaj następujący deklaratywny znacznik między wierszem tabeli (<tr>), który zawiera Password pole TextBox i wiersz tabeli, w którym znajduje się pole wyboru Zapamiętaj mnie następnym razem:

<tr>
 <td align="right">
 <asp:Label ID="EmailLabel" runat="server" AssociatedControlID="Email">Email:</asp:Label>
 </td>
 <td>
 <asp:TextBox ID="Email" runat="server"></asp:TextBox>
 <asp:RequiredFieldValidator ID="EmailRequired" runat="server"
 ControlToValidate="Email" ErrorMessage="Email is required."
 ToolTip="Email is required." ValidationGroup="myLogin">*</asp:RequiredFieldValidator>
 </td>
</tr>

Po dodaniu pola Email TextBox odwiedź stronę za pośrednictwem przeglądarki. Jak pokazano na rysunku 8, interfejs użytkownika kontrolki Logowania zawiera teraz trzecie pole tekstowe.

Kontrolka logowania zawiera teraz pole tekstowe adresu Email użytkownika

Rysunek 8. Kontrolka logowania zawiera teraz pole tekstowe adresu Email użytkownika (kliknij, aby wyświetlić obraz pełnowymiarowy)

Na tym etapie kontrolka Login nadal używa Membership.ValidateUser metody do sprawdzania poprawności podanych poświadczeń. W związku z tym wartość wprowadzona w polu Email TextBox nie ma wpływu na to, czy użytkownik może się zalogować. W kroku 3 przyjrzymy się, jak zastąpić logikę uwierzytelniania kontrolki logowania, tak aby poświadczenia zostały uznane za prawidłowe tylko wtedy, gdy nazwa użytkownika i hasło są prawidłowe, a podany adres e-mail jest zgodny z adresem e-mail w pliku.

Krok 3. Modyfikowanie logiki uwierzytelniania kontrolki logowania

Gdy gość dostarcza swoje poświadczenia i klika przycisk Zaloguj, zostanie wyświetlony komunikat zwrotny i kontrolka Logowania postępuje za pośrednictwem przepływu pracy uwierzytelniania. Przepływ pracy rozpoczyna się od podniesienia LoggingIn zdarzenia. Wszystkie programy obsługi zdarzeń skojarzone z tym zdarzeniem mogą anulować operację logowania, ustawiając e.Cancel właściwość na True.

Jeśli operacja logowania nie zostanie anulowana, przepływ pracy postępuje przez podniesienie Authenticate zdarzenia. Jeśli istnieje procedura obsługi zdarzeń Authenticate , jest odpowiedzialna za określenie, czy podane poświadczenia są prawidłowe, czy nie. Jeśli nie określono procedury obsługi zdarzeń, kontrolka Login używa Membership.ValidateUser metody w celu określenia ważności poświadczeń.

Jeśli podane poświadczenia są prawidłowe, zostanie utworzony bilet uwierzytelniania formularzy, LoggedIn zdarzenie zostanie podniesione, a użytkownik zostanie przekierowany do odpowiedniej strony. Jeśli jednak poświadczenia zostaną uznane za nieprawidłowe, LoginError zostanie zgłoszone zdarzenie i zostanie wyświetlony komunikat informujący użytkownika, że ich poświadczenia były nieprawidłowe. Domyślnie po niepowodzeniu kontrolka Login po prostu ustawia FailureText właściwość Text kontrolki Etykieta na komunikat o niepowodzeniu ( Próba logowania nie powiodła się. Spróbuj ponownie ). Jeśli jednak właściwość kontrolki FailureAction Logowania jest ustawiona na RedirectToLoginPage, kontrolka Logowania wystawia element na Response.Redirect stronie logowania dołączając parametr loginfailure=1 querystring (co powoduje wyświetlenie komunikatu o błędzie kontrolki Logowania).

Rysunek 9 zawiera wykres przepływowy przepływu pracy uwierzytelniania.

Przepływ pracy uwierzytelniania kontrolki logowania

Rysunek 9. Przepływ pracy uwierzytelniania kontrolki logowania (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Jeśli zastanawiasz się, kiedy użyjesz FailureActionopcji strony , RedirectToLogin rozważ następujący scenariusz. W tej chwili nasza Site.master strona wzorcowa ma obecnie tekst Witaj, nieznajomy wyświetlany w lewej kolumnie po odwiedzeniu przez anonimowego użytkownika, ale załóżmy, że chcemy zastąpić ten tekst kontrolką Login. Pozwoliłoby to użytkownikowi anonimowemu zalogować się z dowolnej strony w witrynie, zamiast wymagać od nich bezpośredniego odwiedzenia strony logowania. Jeśli jednak użytkownik nie mógł zalogować się za pomocą kontrolki Logowania renderowanej przez stronę wzorcową, może to mieć sens, aby przekierować je do strony logowania (Login.aspx), ponieważ ta strona prawdopodobnie zawiera dodatkowe instrukcje, linki i inną pomoc — na przykład linki do tworzenia nowego konta lub pobierania utraconego hasła — które nie zostały dodane do strony wzorcowej.

Tworzenie programu obsługi zdarzeńAuthenticate

Aby podłączyć naszą niestandardową logikę uwierzytelniania, musimy utworzyć procedurę obsługi zdarzeń dla zdarzenia kontrolki Authenticate Logowania. Utworzenie procedury obsługi zdarzeń Authenticate dla zdarzenia spowoduje wygenerowanie następującej definicji procedury obsługi zdarzeń:

Protected Sub myLogin_Authenticate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.AuthenticateEventArgs) Handles myLogin.Authenticate

End Sub

Jak widać, Authenticate procedura obsługi zdarzeń jest przekazywana obiekt typu AuthenticateEventArgs jako drugi parametr wejściowy. Klasa AuthenticateEventArgs zawiera właściwość logiczną o nazwie Authenticated , która służy do określenia, czy podane poświadczenia są prawidłowe. Następnie naszym zadaniem jest napisanie kodu, który określa, czy podane poświadczenia są prawidłowe, czy nie, i odpowiednio ustawić e.Authenticate właściwość.

Określanie i weryfikowanie podanych poświadczeń

Użyj właściwości i Password kontrolki UserName Logowania, aby określić poświadczenia nazwy użytkownika i hasła wprowadzone przez użytkownika. Aby określić wartości wprowadzone w dodatkowych kontrolkach sieci Web (takich jak Email TextBox dodane w poprzednim kroku), użyj LoginControlID.FindControl("controlID") w celu uzyskania programowego odwołania do kontrolki sieci Web w szablonie, którego ID właściwość jest równa controlID. Aby na przykład uzyskać odwołanie do pola Email TextBox, użyj następującego kodu:

Dim EmailTextBox As TextBox = CType(myLogin.FindControl("Email"), TextBox)

Aby zweryfikować poświadczenia użytkownika, należy wykonać dwie czynności:

  1. Upewnij się, że podana nazwa użytkownika i hasło są prawidłowe
  2. Upewnij się, że wprowadzony adres e-mail jest zgodny z adresem e-mail w pliku, na który użytkownik próbuje się zalogować

Aby wykonać pierwsze sprawdzenie, możemy po prostu użyć Membership.ValidateUser metody, jak pokazano w kroku 1. W przypadku drugiego sprawdzenia musimy określić adres e-mail użytkownika, abyśmy mogli porównać go z adresem e-mail wprowadzonym w kontrolce TextBox. Aby uzyskać informacje o określonym użytkowniku, użyj Membership metody klasyGetUser.

Metoda GetUser ma wiele przeciążeń. Jeśli jest używany bez przekazywania żadnych parametrów, zwraca informacje o aktualnie zalogowanym użytkowniku. Aby uzyskać informacje o określonym użytkowniku, wywołaj GetUser przekazywanie nazwy użytkownika. W każdym razie GetUser zwraca MembershipUser obiekt, który ma właściwości, takie jak UserName, Email, IsApproved, IsOnlinei tak dalej.

Poniższy kod implementuje te dwa testy. Jeśli oba te elementy są przekazywane, e.Authenticate zostanie ustawiona wartość True, w przeciwnym razie zostanie przypisana Falsewartość .

Protected Sub myLogin_Authenticate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.AuthenticateEventArgs) Handles myLogin.Authenticate
    
 ' Get the email address entered
 Dim EmailTextBox As TextBox = CType(myLogin.FindControl("Email"), TextBox)
 Dim email As String = EmailTextBox.Text.Trim()
    
 ' Verify that the username/password pair is valid
 If Membership.ValidateUser(myLogin.UserName, myLogin.Password) Then

 ' Username/password are valid, check email
 Dim usrInfo As MembershipUser = Membership.GetUser(myLogin.UserName)
    
 If usrInfo IsNot Nothing AndAlso String.Compare(usrInfo.Email, email, True) = 0 Then
 ' Email matches, the credentials are valid
 e.Authenticated = True
 Else
 ' Email address is invalid...
 e.Authenticated = False
 End If
 Else
 ' Username/password are not valid...
 e.Authenticated = False
 End If
End Sub

Przy użyciu tego kodu spróbuj zalogować się jako prawidłowy użytkownik, wprowadzając prawidłową nazwę użytkownika, hasło i adres e-mail. Spróbuj ponownie, ale tym razem celowo użyj nieprawidłowego adresu e-mail (zobacz Rysunek 10). Na koniec spróbuj go po raz trzeci przy użyciu nieistniejącej nazwy użytkownika. W pierwszym przypadku powinno nastąpić pomyślne zalogowanie do witryny, ale w dwóch ostatnich przypadkach powinien zostać wyświetlony komunikat o nieprawidłowych poświadczeniach kontrolki logowania.

Tito nie może się zalogować podczas podawania nieprawidłowego adresu Email

Rysunek 10. Tito nie może się zalogować podczas podawania nieprawidłowego adresu Email (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Zgodnie z opisem w sekcji How the Membership Framework Handles Invalid Login Attempts (Jak struktura członkostwa obsługuje nieprawidłowe próby logowania) w kroku 1, gdy Membership.ValidateUser metoda jest wywoływana i przekazuje nieprawidłowe poświadczenia, śledzi nieprawidłową próbę logowania i blokuje użytkownika, jeśli przekroczy określony próg nieprawidłowych prób w określonym przedziale czasu. Ponieważ nasza niestandardowa logika uwierzytelniania wywołuje ValidateUser metodę, nieprawidłowe hasło dla prawidłowej nazwy użytkownika zwiększa nieprawidłowy licznik prób logowania, ale ten licznik nie jest zwiększany w przypadku, gdy nazwa użytkownika i hasło są prawidłowe, ale adres e-mail jest nieprawidłowy. Istnieje prawdopodobieństwo, że to zachowanie jest odpowiednie, ponieważ jest mało prawdopodobne, aby haker znał nazwę użytkownika i hasło, ale musi użyć technik siłowych w celu ustalenia adresu e-mail użytkownika.

Krok 4. Ulepszenie komunikatu o nieprawidłowych poświadczeniach kontrolki logowania

Gdy użytkownik próbuje zalogować się przy użyciu nieprawidłowych poświadczeń, w kontrolce Logowania zostanie wyświetlony komunikat wyjaśniający, że próba logowania nie powiodła się. W szczególności kontrolka wyświetla komunikat określony przez jego FailureText właściwość, która ma wartość domyślną Próby logowania nie powiodła się. Spróbuj ponownie.

Pamiętaj, że istnieje wiele powodów, dla których poświadczenia użytkownika mogą być nieprawidłowe:

  • Nazwa użytkownika może nie istnieć
  • Nazwa użytkownika istnieje, ale hasło jest nieprawidłowe
  • Nazwa użytkownika i hasło są prawidłowe, ale użytkownik nie został jeszcze zatwierdzony
  • Nazwa użytkownika i hasło są prawidłowe, ale użytkownik jest zablokowany (najprawdopodobniej, ponieważ przekroczył liczbę nieprawidłowych prób logowania w określonym przedziale czasu)

W przypadku używania niestandardowej logiki uwierzytelniania mogą istnieć inne przyczyny. Na przykład w kodzie napisanym w kroku 3 nazwa użytkownika i hasło mogą być prawidłowe, ale adres e-mail może być niepoprawny.

Niezależnie od tego, dlaczego poświadczenia są nieprawidłowe, kontrolka Logowania wyświetla ten sam komunikat o błędzie. Ten brak opinii może być mylący dla użytkownika, którego konto nie zostało jeszcze zatwierdzone lub kto został zablokowany. Przy odrobinie pracy możemy jednak wyświetlić bardziej odpowiedni komunikat kontrolki Logowania.

Za każdym razem, gdy użytkownik próbuje zalogować się przy użyciu nieprawidłowych poświadczeń, kontrolka Logowania zgłasza swoje LoginError zdarzenie. Przejdź do przodu i utwórz procedurę obsługi zdarzeń dla tego zdarzenia i dodaj następujący kod:

Protected Sub myLogin_LoginError(ByVal sender As Object, ByVal e As System.EventArgs) Handles myLogin.LoginError
    
 ' Determine why the user could not login...
 myLogin.FailureText = "Your login attempt was not successful. Please try again."
    
 ' Does there exist a User account for this user?
 Dim usrInfo As MembershipUser = Membership.GetUser(myLogin.UserName)

 If usrInfo IsNot Nothing Then
 ' Is this user locked out?
 If usrInfo.IsLockedOut Then
 myLogin.FailureText = "Your account has been locked out because of too many invalid login attempts. Please contact the administrator to have your account unlocked."
 ElseIf Not usrInfo.IsApproved Then
 myLogin.FailureText = "Your account has not yet been approved. You cannot login until an administrator has approved your account."
 End If
 End If
End Sub

Powyższy kod rozpoczyna się od ustawienia właściwości kontrolki FailureText Login na wartość domyślną ( Próba logowania nie powiodła się. Spróbuj ponownie ). Następnie sprawdza, czy podano nazwę użytkownika mapuje na istniejące konto użytkownika. Jeśli tak, skonsultuje się z wynikowymi MembershipUser obiektami IsLockedOut i IsApproved właściwościami, aby ustalić, czy konto zostało zablokowane lub nie zostało jeszcze zatwierdzone. W obu przypadkach FailureText właściwość jest aktualizowana do odpowiedniej wartości.

Aby przetestować ten kod, celowo spróbuj zalogować się jako istniejący użytkownik, ale użyj nieprawidłowego hasła. Zrób to pięć razy z rzędu w przedziale czasu 10 minut, a konto zostanie zablokowane. Jak pokazano na rysunku 11, kolejne próby logowania zawsze kończą się niepowodzeniem (nawet przy poprawnym haśle), ale teraz będą wyświetlane bardziej opisowe Konto zostało zablokowane z powodu zbyt wielu nieprawidłowych prób logowania. Skontaktuj się z administratorem, aby mieć odblokowane konto.

Tito wykonał zbyt wiele nieprawidłowych prób logowania i został zablokowany

Rysunek 11. Tito wykonał zbyt wiele nieprawidłowych prób logowania i został zablokowany (kliknij, aby wyświetlić obraz pełnowymiarowy)

Podsumowanie

Przed rozpoczęciem tego samouczka nasza strona logowania zweryfikowała podane poświadczenia względem trwale zakodowanej listy par nazwy użytkownika/hasła. W tym samouczku zaktualizowaliśmy stronę, aby zweryfikować poświadczenia w strukturze członkostwa. W kroku 1 przyjrzeliśmy się programowe użyciu Membership.ValidateUser metody. W kroku 2 zastąpiliśmy ręcznie utworzony interfejs użytkownika i kod kontrolką Login.

Kontrolka Login renderuje standardowy interfejs użytkownika logowania i automatycznie weryfikuje poświadczenia użytkownika względem struktury członkostwa. Ponadto w przypadku prawidłowych poświadczeń kontrolka Login podpisuje użytkownika za pomocą uwierzytelniania formularzy. Krótko mówiąc, środowisko użytkownika logowania w pełni funkcjonalne jest dostępne, przeciągając kontrolkę Logowania na stronę, bez dodatkowego deklaratywnego znaczników ani kodu. Co więcej, kontrolka Logowania jest wysoce dostosowywalna, co pozwala na uzyskanie precyzyjnego stopnia kontroli zarówno nad renderowanym interfejsem użytkownika, jak i logiką uwierzytelniania.

W tym momencie odwiedzający naszą witrynę internetową mogą utworzyć nowe konto użytkownika i zalogować się do witryny, ale musimy jeszcze przyjrzeć się ograniczeniu dostępu do stron na podstawie uwierzytelnionego użytkownika. Obecnie każdy użytkownik, uwierzytelniony lub anonimowy, może wyświetlić dowolną stronę w naszej witrynie. Oprócz kontrolowania dostępu do stron naszej witryny na podstawie użytkownika możemy mieć pewne strony, których funkcjonalność zależy od użytkownika. W następnym samouczku przedstawiono sposób ograniczania dostępu i funkcji na stronie na podstawie zalogowanego użytkownika.

Szczęśliwe programowanie!

Dalsze informacje

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

Informacje o autorze

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

Specjalne podziękowania

Ta seria samouczków została sprawdzona przez wielu pomocnych recenzentów. Recenzenci z tego samouczka byli Teresa Murphy i Michael Olivero. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.