Udostępnij za pośrednictwem


Odzyskiwanie i zmienianie haseł (C#)

Autor: Scott Mitchell

Uwaga

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

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

ASP.NET zawiera dwie kontrolki sieci Web ułatwiające odzyskiwanie i zmienianie haseł. Kontrolka PasswordRecovery umożliwia odwiedzającym odzyskanie utraconego hasła. Kontrolka ChangePassword umożliwia użytkownikowi aktualizowanie hasła. Podobnie jak w przypadku innych kontrolek sieci Web związanych z logowaniem, które widzieliśmy w tej serii samouczków, kontrolki PasswordRecovery i ChangePassword współpracują ze strukturą członkostwa w tle w celu zresetowania lub zmodyfikowania haseł użytkowników.

Wprowadzenie

Między witrynami internetowymi dla mojego banku, firmy użyteczności publicznej, firmy telefonicznej, kont e-mail i spersonalizowanych portali internetowych, jak większość ludzi, mają dziesiątki różnych haseł do zapamiętania. Przy tak wielu poświadczeniach do zapamiętania w tych dniach, nie jest rzadkością, aby ludzie zapominali o swoim haśle. Aby to uwzględnić, witryny internetowe oferujące konta użytkowników muszą zawierać sposób na odzyskanie hasła przez użytkownika. Ten proces zwykle obejmuje generowanie nowego, losowego hasła i wysyłanie go pocztą e-mail na adres e-mail użytkownika w pliku. Po otrzymaniu nowego hasła większość użytkowników powróci do witryny i zmień swoje hasło z losowo wygenerowanego hasła na bardziej pamiętny.

ASP.NET zawiera dwie kontrolki sieci Web ułatwiające odzyskiwanie i zmienianie haseł. Kontrolka PasswordRecovery umożliwia odwiedzającym odzyskanie utraconego hasła. Kontrolka ChangePassword umożliwia użytkownikowi aktualizowanie hasła. Podobnie jak w przypadku innych kontrolek sieci Web związanych z logowaniem, które widzieliśmy w tej serii samouczków, kontrolki PasswordRecovery i ChangePassword współpracują ze strukturą członkostwa w tle w celu zresetowania lub zmodyfikowania haseł użytkowników.

W tym samouczku przeanalizujemy użycie tych dwóch kontrolek. Zobaczymy również, jak programowo zmienić i zresetować hasło użytkownika za pomocą MembershipUser metod i ResetPassword klasyChangePassword.

Krok 1. Pomoc użytkownikom w odzyskiwaniu utraconych haseł

Wszystkie witryny internetowe obsługujące konta użytkowników muszą zapewnić użytkownikom pewien mechanizm odzyskiwania zapomnianych haseł. Dobrą wiadomością jest to, że zaimplementowanie takich funkcji w ASP.NET jest proste dzięki kontrolce PasswordRecovery Web. Kontrolka PasswordRecovery renderuje interfejs, który monituje użytkownika o podanie nazwy użytkownika i, w razie potrzeby, odpowiedzi na pytanie zabezpieczające. Następnie e-maile użytkownika jego hasło.

Uwaga

Ponieważ wiadomości e-mail są przesyłane za pośrednictwem przewodu w postaci zwykłego tekstu, istnieją zagrożenia bezpieczeństwa związane z wysyłaniem hasła użytkownika za pośrednictwem poczty e-mail.

Kontrolka PasswordRecovery składa się z trzech widoków:

  • UserName — monituje gościa o podanie nazwy użytkownika. Jest to widok początkowy.
  • Pytanie — wyświetla nazwę użytkownika i pytanie zabezpieczające jako tekst wraz z polem TextBox, aby użytkownik mógł wprowadzić odpowiedź na pytanie zabezpieczające.
  • Powodzenie — wyświetla komunikat informujący użytkownika o tym, że jego hasło zostało przesłane pocztą e-mail.

Wyświetlane widoki i akcje wykonywane przez kontrolkę PasswordRecovery zależą od następujących ustawień konfiguracji członkostwa:

  • RequiresQuestionAndAnswer
  • EnablePasswordRetrieval
  • EnablePasswordReset

Ustawienie struktury RequiresQuestionAndAnswer członkostwa wskazuje, czy użytkownicy muszą określić pytanie zabezpieczające i odpowiedzieć podczas rejestrowania się na koncie. Jak omówiliśmy w samouczku Tworzenie kont użytkowników, jeśli RequiresQuestionAndAnswer wartość True (wartość domyślna), interfejs CreateUserWizard zawiera kontrolki TextBox dla pytania i odpowiedzi nowego użytkownika; jeśli RequiresQuestionAndAnswer jest to Fałsz, nie są zbierane żadne takie informacje. Podobnie, jeśli RequiresQuestionAndAnswer ma wartość True, kontrolka PasswordRecovery wyświetla widok Pytanie po wprowadzeniu nazwy użytkownika. Hasło zostanie odzyskane tylko wtedy, gdy użytkownik wprowadzi poprawną odpowiedź zabezpieczeń. Jeśli RequiresQuestionAndAnswer jednak ma wartość False, kontrolka PasswordRecovery przenosi się bezpośrednio z widoku UserName do widoku Powodzenie.

Po podaniu nazwy użytkownika lub jego nazwy użytkownika i odpowiedzi na zabezpieczenia, jeśli RequiresQuestionAndAnswer ma wartość True — hasłoOdzyskiwania e-mail użytkownika jego hasło. EnablePasswordRetrieval Jeśli opcja ma wartość True, użytkownik otrzymuje wiadomość e-mail z bieżącym hasłem. Jeśli jest ustawiona wartość Fałsz i EnablePasswordReset jest ustawiona na wartość True, kontrolka PasswordRecovery generuje nowe, losowe hasło dla użytkownika i wiadomości e-mail z tym nowym hasłem. Jeśli obie EnablePasswordRetrieval wartości i EnablePasswordReset mają wartość False, kontrolka PasswordRecovery zgłasza wyjątek.

Uwaga

Pamiętaj, że SqlMembershipProvider hasła użytkowników są przechowywane w jednym z trzech formatów: Clear, Hashed (wartość domyślna) lub Encrypted. Używany mechanizm magazynu zależy od ustawień konfiguracji członkostwa; aplikacja demonstracyjna używa formatu hasła skrótu. W przypadku korzystania z formatu hasła skrótu opcja musi być ustawiona na Wartość Fałsz, EnablePasswordRetrieval ponieważ system nie może określić rzeczywistego hasła użytkownika z skrótu wersji przechowywanej w bazie danych.

Rysunek 1 ilustruje wpływ interfejsu i zachowania passwordRecovery na konfigurację członkostwa.

Kontrolka RequiresQuestionAndAnswer, EnablePasswordRetrieval i EnablePasswordReset wpływają na wygląd i zachowanie kontrolki PasswordRecovery

Rysunek 1. RequiresQuestionAndAnswerEnablePasswordRetrievalWygląd i zachowanie kontrolki PasswordRecovery (EnablePasswordResetKliknij, aby wyświetlić obraz o pełnym rozmiarze)

Uwaga

W samouczku Tworzenie schematu członkostwa w programie SQL Server skonfigurowaliśmy dostawcę członkostwa, ustawiając wartość RequiresQuestionAndAnswer True, EnablePasswordRetrieval wartość False i EnablePasswordReset true.

Używanie kontrolki PasswordRecovery

Przyjrzyjmy się użyciu kontrolki PasswordRecovery na stronie ASP.NET. Otwórz RecoverPassword.aspx i przeciągnij i upuść kontrolkę PasswordRecovery z przybornika do projektanta; ustaw ją ID na RecoverPwd. Podobnie jak kontrolki Login i CreateUserWizard Web, widoki kontrolki PasswordRecovery renderuje bogaty interfejs złożony, który obejmuje kontrolki Etykiety, TextBoxes, Przyciski i walidacja. Wygląd widoków można dostosować za pomocą właściwości stylu kontrolki lub konwertując widoki na szablony. Zostawię to jako ćwiczenie dla zainteresowanego czytelnika.

Gdy użytkownik odwiedzi tę stronę, wprowadzi nazwę użytkownika i kliknij przycisk Prześlij. Ponieważ właściwość ma ustawioną RequiresQuestionAndAnswer wartość True w ustawieniach konfiguracji członkostwa, kontrolka PasswordRecovery wyświetli następnie widok Pytanie. Gdy użytkownik wprowadzi poprawną odpowiedź na zabezpieczenia i kliknie pozycję Prześlij, kontrolka PasswordRecovery zaktualizuje hasło użytkownika do losowo wygenerowanego hasła, a następnie wyśle to hasło na adres e-mail w pliku. Wszystko to było możliwe bez konieczności pisania jednego wiersza kodu!

Przed przetestowanie tej strony istnieje jeden ostatni element konfiguracji, który ma tendencję do: musimy określić ustawienia dostarczania poczty w pliku Web.config. Kontrolka PasswordRecovery opiera się na tych ustawieniach wysyłania wiadomości e-mail.

Konfiguracja dostarczania poczty jest określana za pomocą <system.net> elementu<mailSettings> . <smtp> Użyj elementu , aby wskazać metodę dostarczania i wartość domyślną Od adresu. Poniższy znacznik konfiguruje ustawienia poczty do używania sieciowego serwera SMTP o nazwie smtp.example.com na porcie 25 oraz przy użyciu poświadczeń nazwy użytkownika/hasła nazwy użytkownika i hasła.

Uwaga

<system.net> jest elementem podrzędnym elementu głównego <configuration> i elementem równorzędnym elementu <system.web>. W związku z tym nie umieszczaj <system.net> elementu w elemecie <system.web> , zamiast tego umieść go na tym samym poziomie.

<configuration>
 ...
 <system.net>
 <mailSettings>
 <smtp deliveryMethod="Network" from="youraddress@example.com">
 <network
 host="smtp.example.com"
 userName="username"
 password="password"
 port="25" />
 </smtp>
 </mailSettings>
 </system.net>
</configuration>

Oprócz korzystania z serwera SMTP w sieci można również określić katalog odbioru, w którym powinny być wysyłane wiadomości e-mail.

Po skonfigurowaniu ustawień SMTP odwiedź RecoverPassword.aspx stronę za pośrednictwem przeglądarki. Najpierw spróbuj wprowadzić nazwę użytkownika, która nie istnieje w magazynie użytkowników. Jak pokazano na rysunku 2, kontrolka PasswordRecovery wyświetla komunikat wskazujący, że nie można uzyskać dostępu do informacji o użytkowniku. Tekst wiadomości można dostosować za pomocą właściwości kontrolki.UserNameFailureText

Jeśli wprowadzono nieprawidłową nazwę użytkownika, zostanie wyświetlony komunikat o błędzie

Rysunek 2. Komunikat o błędzie jest wyświetlany, jeśli wprowadzono nieprawidłową nazwę użytkownika (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Teraz wprowadź nazwę użytkownika. Użyj nazwy użytkownika konta w systemie z adresem e-mail, do którego możesz uzyskać dostęp i którego odpowiedzi na zabezpieczenia znasz. Po wprowadzeniu nazwy użytkownika i kliknięciu przycisku Prześlij kontrolka PasswordRecovery wyświetla widok Pytanie. Podobnie jak w widoku UserName, jeśli wprowadzisz nieprawidłową odpowiedź, kontrolka PasswordRecovery wyświetla komunikat o błędzie (zobacz Rysunek 3). QuestionFailureText Użyj właściwości , aby dostosować ten komunikat o błędzie.

Jeśli użytkownik wprowadzi nieprawidłową odpowiedź zabezpieczeń, zostanie wyświetlony komunikat o błędzie

Rysunek 3. Komunikat o błędzie jest wyświetlany, jeśli użytkownik wprowadzi nieprawidłową odpowiedź zabezpieczeń (kliknij, aby wyświetlić obraz pełnowymiarowy)

Na koniec wprowadź poprawną odpowiedź na zabezpieczenia i kliknij przycisk Prześlij. W tle kontrolka PasswordRecovery generuje losowe hasło, przypisuje je do konta użytkownika, wysyła wiadomość e-mail z informacją o nowym haśle (zobacz Rysunek 4), a następnie wyświetla widok Powodzenie.

Użytkownik otrzymuje wiadomość e-mail z nowym hasłem

Rysunek 4. Użytkownik otrzymuje wiadomość e-mail z nowym hasłem (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Dostosowywanie wiadomości e-mail

Domyślna wiadomość e-mail wysłana przez kontrolkę PasswordRecovery jest dość nudna (zobacz Rysunek 4). Wiadomość jest wysyłana z konta określonego <smtp> w atrybucie elementu from z tematem Hasło i treść zwykłego tekstu:

Wróć do witryny i zaloguj się, korzystając z poniższych informacji.

Nazwa użytkownika: nazwa użytkownika

Hasło: hasło

Ten komunikat można dostosować programowo za pomocą programu obsługi zdarzeń dla zdarzenia kontrolki SendingMail PasswordRecovery lub deklaratywnie za pośrednictwem MailDefinition właściwości . Przyjrzyjmy się obu tym opcjom.

Zdarzenie SendingMail jest uruchamiane bezpośrednio przed wysłaniem wiadomości e-mail i jest naszą ostatnią szansą programowego dostosowania wiadomości e-mail. Po wystąpieniu tego zdarzenia program obsługi zdarzeń jest przekazywany obiekt typu MailMessageEventArgs, którego Message właściwość zawiera odwołanie do wiadomości e-mail, która ma zostać wysłana.

Utwórz program obsługi zdarzeń dla SendingMail zdarzenia i dodaj następujący kod, który programowo dodaje webmaster@example.com do listy CC.

protected void RecoverPwd_SendingMail(object sender, MailMessageEventArgs e)
{
    e.Message.CC.Add("webmaster@example.com");
}

Wiadomość e-mail można również skonfigurować za pomocą środków deklaratywnych. Właściwość PasswordRecovery MailDefinition jest obiektem typu MailDefinition. Klasa MailDefinition oferuje wiele właściwości związanych z pocztą e-mail, w tym From, CC, Priority, Subject, IsBodyHtmlBodyFileNamei innych. Na początek ustaw Subject właściwość na bardziej opisową niż ta używana domyślnie ( Hasło ), taka jak Hasło została zresetowana...

Aby dostosować treść wiadomości e-mail, musimy utworzyć oddzielny plik szablonu wiadomości e-mail zawierający zawartość treści. Zacznij od utworzenia nowego folderu w witrynie internetowej o nazwie EmailTemplates. Następnie dodaj nowy plik tekstowy do tego folderu o nazwie PasswordRecovery.txt i dodaj następującą zawartość:

Your password has been reset, <%UserName%>!

According to our records, you have requested that your password be reset. Your new
password is: <%Password%>

If you have any questions or trouble logging on please contact a site administrator.

Thank you!

Zwróć uwagę na użycie symboli zastępczych <%UserName%> i <%Password%>. Kontrolka PasswordRecovery automatycznie zastępuje te dwa symbole zastępcze nazwą użytkownika i odzyskanym hasłem przed wysłaniem wiadomości e-mail.

Na koniec wskaż MailDefinitionwłaściwość "sBodyFileName" do właśnie utworzonego szablonu wiadomości e-mail (~/EmailTemplates/PasswordRecovery.txt).

Po wprowadzeniu tych zmian ponownie sprawdź RecoverPassword.aspx stronę i wprowadź swoją nazwę użytkownika i odpowiedź na zabezpieczenia. Otrzymasz wiadomość e-mail, która wygląda jak na rysunku 5. Należy pamiętać, że webmaster@example.com cc'd i że temat i treść zostały zaktualizowane.

Temat, treść i lista CC zostały zaktualizowane

Rysunek 5. Zaktualizowano listę Temat, Treść i DW (kliknij, aby wyświetlić obraz pełnowymiarowy)

Aby wysłać wiadomość e-mail w formacie HTML ustawioną IsBodyHtml na wartość True (wartość domyślna to Fałsz) i zaktualizuj szablon wiadomości e-mail w celu uwzględnienia kodu HTML.

Właściwość MailDefinition nie jest unikatowa dla klasy PasswordRecovery. Jak zobaczymy w kroku 2, kontrolka MailDefinition ChangePassword oferuje również właściwość. Ponadto kontrolka CreateUserWizard zawiera taką właściwość, którą można skonfigurować w celu automatycznego wysyłania powitalnej wiadomości e-mail do nowych użytkowników.

Uwaga

Obecnie nie ma żadnych linków w nawigacji po lewej stronie w celu dotarcia do RecoverPassword.aspx strony. Użytkownik byłby zainteresowany odwiedzaniem tej strony tylko wtedy, gdy nie mogła pomyślnie zalogować się do witryny. W związku z tym zaktualizuj Login.aspx stronę, aby zawierała link do RecoverPassword.aspx strony.

Programowe resetowanie hasła użytkownika

Podczas resetowania hasła użytkownika kontrolka PasswordRecovery wywołuje MembershipUser metodę obiektuResetPassword. Ta metoda ma dwa przeciążenia:

  • ResetPassword — resetuje hasło użytkownika. Użyj tego przeciążenia, jeśli RequiresQuestionAndAnswer ma wartość False.
  • ResetPassword(securityAnswer) — resetuje hasło użytkownika tylko wtedy, gdy podane zabezpieczeniaAnswer jest poprawny. Użyj tego przeciążenia, jeśli RequiresQuestionAndAnswer ma wartość True.

Oba przeciążenia zwracają nowe, losowo wygenerowane hasło.

Podobnie jak w przypadku innych metod w strukturze członkostwa, ResetPassword metoda deleguje do skonfigurowanego dostawcy. Obiekt SqlMembershipProvider wywołuje procedurę aspnet_Membership_ResetPassword składowaną, przekazując nazwę użytkownika, nowe hasło i podaną odpowiedź na hasło, między innymi pola. Procedura składowana gwarantuje, że odpowiedź na hasło jest zgodna, a następnie aktualizuje hasło użytkownika.

Kilka uwag dotyczących implementacji niskiego poziomu:

  • Zablokowany użytkownik nie może zresetować hasła. Jednak użytkownik niezatwierdzony może. Bardziej szczegółowo omówimy stany zablokowane i zatwierdzone w samouczku Unlocking and Approved User Accounts (Odblokowywanie i zatwierdzanie kont użytkowników).
  • Jeśli odpowiedź na hasło jest niepoprawna, liczba nieudanych prób odpowiedzi na hasło użytkownika jest zwiększana. Jeśli w określonym przedziale czasu wystąpi określona liczba nieprawidłowych prób odpowiedzi na zabezpieczenia, użytkownik zostanie zablokowany.

Wyraz dotyczący sposobu generowania losowych haseł

Losowo wygenerowane hasła wyświetlane w wiadomościach e-mail na rysunkach 4 i 5 są tworzone przez metodę klasy GeneratePassword Członkostwa. Ta metoda akceptuje dwa paramatory wejściowe liczby całkowitej — długość i numberOfNonAlphanumericCharacters — i zwraca ciąg o długości co najmniej długości z co najmniej liczbąOfNonAlphanumericCharacters liczbą znaków innych niż alfanumeryczne. Gdy ta metoda jest wywoływana z klas członkostwa lub formantów sieci Web związanych z logowaniem, wartości tych dwóch parametrów są określane odpowiednio przez właściwości i MinRequiredNonalphanumericCharacters konfiguracji MinRequiredPasswordLength członkostwa, które zostały ustawione odpowiednio na 7 i 1.

Metoda GeneratePassword używa kryptograficznie silnego generatora liczb losowych, aby upewnić się, że nie ma stronniczość co do wybranych losowych znaków. Ponadto jest to public, co oznacza, GeneratePassword że można go używać bezpośrednio z aplikacji ASP.NET, jeśli musisz wygenerować losowe ciągi lub hasła.

Uwaga

Klasa SqlMembershipProvider zawsze generuje losowe hasło co najmniej 14 znaków, więc jeśli MinRequiredPasswordLength wartość jest mniejsza niż 14, jej wartość jest ignorowana.

Krok 2. Zmienianie haseł

Losowe hasła są trudne do zapamiętania. Rozważ hasło pokazane na rysunku 4: WWGUZv(f2yM:Bd. Spróbuj zobowiązać ją do pamięci! Nie trzeba dodawać, że po wysłaniu przez użytkownika losowo wygenerowanego hasła tego rodzaju będzie chciała zmienić hasło na coś bardziej pamiętnego.

Użyj kontrolki ChangePassword, aby utworzyć interfejs użytkownika w celu zmiany hasła. Podobnie jak kontrolka PasswordRecovery, kontrolka ChangePassword składa się z dwóch widoków: Zmień hasło i Powodzenie. Widok Zmień hasło monituje użytkownika o stare i nowe hasła. Po podaniem poprawnego starego hasła i nowego hasła spełniającego minimalne wymagania dotyczące długości i znaków innych niż alfanumeryczne kontrolka ChangePassword aktualizuje hasło użytkownika i wyświetla widok Powodzenie.

Uwaga

Kontrolka ChangePassword modyfikuje hasło użytkownika, wywołując metodę MembershipUserobiektuChangePassword. Metoda ChangePassword akceptuje dwa string parametry wejściowe - oldPassword i newPassword- i aktualizuje konto użytkownika za pomocą nowegoPasswordu, zakładając, że podany oldPassword jest poprawny.

ChangePassword.aspx Otwórz stronę i dodaj kontrolkę ChangePassword do strony, nazywając ją ChangePwd. W tym momencie widok Projekt powinien wyświetlić widok Zmień hasło (zobacz Rysunek 6). Podobnie jak w przypadku kontrolki PasswordRecovery, można przełączać się między widokami za pomocą tagu inteligentnego kontrolki. Ponadto wygląd tych widoków można dostosowywać za pomocą właściwości stylu assortowanego lub przez przekonwertowanie ich na szablon.

Dodawanie kontrolki ChangePassword do strony

Rysunek 6. Dodawanie kontrolki ChangePassword do strony (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Kontrolka ChangePassword może zaktualizować hasło aktualnie zalogowanego użytkownika lub hasło innego określonego użytkownika. Jak pokazano na rysunku 6, domyślny widok Zmień hasło renderuje tylko trzy kontrolki TextBox: jedno dla starego hasła i dwa dla nowego hasła. Ten interfejs domyślny służy do aktualizowania aktualnie zalogowanego hasła użytkownika.

Aby użyć kontrolki ChangePassword w celu zaktualizowania hasła innego użytkownika, ustaw właściwość kontrolki DisplayUserName na True. Spowoduje to dodanie czwartego pola TextBox do strony z monitem o nazwę użytkownika, którego hasło ma ulec zmianie.

Ustawienie DisplayUserName wartości True jest przydatne, jeśli chcesz zezwolić zalogowanym użytkownikowi na zmianę hasła bez konieczności logowania. Osobiście myślę, że nie ma nic złego w przypadku wymagania od użytkownika zalogowania się przed zezwoleniem jej na zmianę hasła. W związku z tym pozostaw wartość DisplayUserName False (wartość domyślna). Jednak w podejmowaniu tej decyzji zasadniczo uniemożliwiamy anonimowym użytkownikom dotarcie do tej strony. Zaktualizuj reguły autoryzacji adresów URL witryny, aby uniemożliwić użytkownikom anonimowym wizytę w witrynie ChangePassword.aspx. Jeśli musisz odświeżyć pamięć w składni reguły autoryzacji adresu URL, zapoznaj się z samouczkiem dotyczącym autoryzacji opartej na użytkownikach.

Uwaga

Może się wydawać, że DisplayUserName właściwość jest przydatna do umożliwienia administratorom zmiany haseł innych użytkowników. Jednak nawet jeśli DisplayUserName jest ustawiona wartość True, musi być znane i wprowadzone poprawne stare hasło. Omówimy techniki umożliwiające administratorom zmianę haseł użytkowników w kroku 3.

ChangePassword.aspx Odwiedź stronę za pośrednictwem przeglądarki i zmień hasło. Zwróć uwagę, że w przypadku wprowadzenia nowego hasła, które nie spełnia wymagań dotyczących długości hasła i znaków innych niż alfanumeryczne określonych w konfiguracji członkostwa (zobacz Rysunek 7).

Jeśli wprowadzisz nowe hasło, które nie spełnia wymagań dotyczących długości hasła i znaków innych niż alfanumeryczne, zostanie wyświetlony komunikat o błędzie.

Rysunek 7. Dodawanie kontrolki ChangePassword do strony (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Po wprowadzeniu poprawnego starego hasła i prawidłowego nowego hasła hasło zalogowanego użytkownika zostanie zmienione i wyświetlony widok Powodzenie.

Wysyłanie wiadomości e-mail z potwierdzeniem

Domyślnie kontrolka ChangePassword nie wysyła wiadomości e-mail do użytkownika, którego hasło zostało właśnie zaktualizowane. Jeśli chcesz wysłać wiadomość e-mail, po prostu skonfiguruj właściwość kontrolki MailDefinition . Skonfigurujmy kontrolkę ChangePassword, aby użytkownik był wysyłany do wiadomości e-mail w formacie HTML, która zawiera nowe hasło.

Zacznij od utworzenia nowego pliku w folderze EmailTemplates o nazwie ChangePassword.htm. Dodaj następujący znacznik:

<html>
 <body>
 <h2>Your Password Has Been Changed!</h2>
 <p>
 This email confirms that your password has been changed.
 </p>
 <p>
 To log on to the site, use the following credentials:
 </p>
 <table>
 <tr>
 <td>
 <b>Username:</b>
 </td>
 <td>
 <%UserName%>
 </td>
 </tr>
 <tr>
 <td>
 <b>Password:</b>
 </td>
 <td>
 <%Password%>
 </td>
 </tr>
 </table>
 <p>
 If you have any questions or encounter any problems logging in,
 please contact a site administrator.
 </p>
 </body>
</html>

Następnie ustaw właściwości właściwości BodyFileNameIsBodyHtml, i Subject kontrolki MailDefinition ChangePassword na ~/EmailTemplates/ChangePassword.htm, Prawda i Hasło zostało zmienione!, odpowiednio.

Po wprowadzeniu tych zmian ponownie przejdź do strony i ponownie zmień hasło. Tym razem kontrolka ChangePassword wysyła niestandardową, sformatowaną w formacie HTML wiadomość e-mail na adres e-mail użytkownika w pliku (zobacz Rysunek 8).

Wiadomość e-mail informuje użytkownika o zmianie hasła

Rysunek 8. Wiadomość e-mail informuje użytkownika o zmianie hasła (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Krok 3. Zezwolenie administratorom na zmianę haseł użytkowników

Typową funkcją w aplikacjach obsługujących konta użytkowników jest możliwość zmiany haseł innych użytkowników przez użytkownika administracyjnego. Czasami ta funkcja jest wymagana, ponieważ system nie ma możliwości zmiany własnych haseł przez użytkowników. W takim przypadku jedynym sposobem odzyskania zapomnianego hasła przez użytkownika będzie przypisanie im nowego hasła przez administratora. Jednak w przypadku kontrolek PasswordRecovery i ChangePassword użytkownicy administracyjni nie muszą zajmować się zmianą haseł użytkowników, ponieważ użytkownicy mogą to zrobić samodzielnie.

Ale co zrobić, jeśli klient nalega, aby użytkownicy administracyjni mogli zmieniać hasła innych użytkowników? Niestety dodanie tej funkcji może być nieco pracy. Aby zmienić hasło użytkownika, zarówno stare, jak i nowe hasło musi zostać dostarczone do MembershipUser metody obiektu ChangePassword , ale administrator nie powinien wiedzieć hasła użytkownika w celu jego zmodyfikowania.

Jednym z obejść jest najpierw zresetowanie hasła użytkownika, a następnie zmianę go na nowe hasło przy użyciu kodu podobnego do następującego:

MembershipUser usr = Membership.GetUser(username);
string resetPwd = usr.ResetPassword();
usr.ChangePassword(resetPwd, newPassword);

Ten kod rozpoczyna się od pobrania informacji o nazwie użytkownika, czyli użytkowniku, którego hasło administrator chce zmienić. Następnie wywoływana ResetPassword jest metoda, która przypisuje i użytkownikowi nowe, losowe hasło. To losowo wygenerowane hasło jest zwracane przez metodę i przechowywane w zmiennej resetPwd. Teraz, gdy znamy hasło użytkownika, możemy go zmienić za pomocą wywołania metody ChangePassword.

Problem polega na tym, że ten kod działa tylko wtedy, gdy konfiguracja systemu członkostwa jest ustawiona na RequiresQuestionAndAnswer wartość False. Jeśli RequiresQuestionAndAnswer ma wartość True, podobnie jak w przypadku naszej aplikacji, ResetPassword metoda musi zostać przekazana odpowiedzią na zabezpieczenia. W przeciwnym razie zgłosi wyjątek.

Jeśli platforma członkostwa jest skonfigurowana tak, aby wymagała pytania zabezpieczającego i odpowiedzi, a jednak klient nalega, aby administratorzy mogli zmieniać hasła użytkowników, masz trzy opcje:

  • Wyrzuć ręce w powietrze i powiedz klientowi, że jest to tylko jedna rzecz, której nie można zrobić.
  • Ustaw RequiresQuestionAndAnswer wartość False. Powoduje to mniej bezpieczną aplikację. Załóżmy, że złośliwy użytkownik uzyskał dostęp do skrzynki odbiorczej poczty e-mail innego użytkownika. Być może naruszony użytkownik opuścił biurko, aby przejść do lunchu i nie zablokował stacji roboczej, a może dostęp do poczty e-mail z publicznego terminalu i nie wylogował się. W obu przypadkach złośliwy użytkownik może odwiedzić RecoverPassword.aspx stronę i wprowadzić nazwę użytkownika. Następnie system wyśle wiadomość e-mail z odzyskanym hasłem bez monitowania o odpowiedź zabezpieczeń.
  • Pomiń warstwę abstrakcji utworzoną przez platformę członkostwa i pracuj bezpośrednio z bazą danych programu SQL Server. Schemat członkostwa zawiera procedurę składowaną o nazwie aspnet_Membership_SetPassword , która ustawia hasło użytkownika i nie wymaga odpowiedzi na zabezpieczenia ani starego hasła w celu wykonania zadania.

Żadna z tych opcji nie jest szczególnie atrakcyjna, ale tak czasami dzieje się życie dewelopera.

Poszedłem do przodu i zaimplementowałem trzecie podejście, pisząc kod, który pomija Membership klasy i MembershipUser działa bezpośrednio w SecurityTutorials bazie danych.

Uwaga

Dzięki bezpośredniej pracy z bazą danych hermetyzacja zapewniana przez platformę członkostwa jest rozbita. Ta decyzja wiąże nas z SqlMembershipProvider, dzięki czemu nasz kod jest mniej przenośny. Ponadto ten kod może nie działać zgodnie z oczekiwaniami w przyszłych wersjach ASP.NET, jeśli schemat członkostwa ulegnie zmianie. Takie podejście jest obejściem i, podobnie jak większość obejść, nie jest przykładem najlepszych rozwiązań.

Kod ma pewne nieatrakcyjne bity i jest dość długi. W związku z tym nie chcę bałaganu tego samouczka z dogłębnym badaniem tego samouczka. Jeśli chcesz dowiedzieć się więcej, pobierz kod dla tego samouczka i odwiedź ~/Administration/ManageUsers.aspx stronę. Ta strona, która została utworzona w poprzednim samouczku, zawiera listę każdego użytkownika. Zaktualizowano element GridView w celu uwzględnienia linku UserInformation.aspx do strony, przekazując nazwę użytkownika wybranego użytkownika za pomocą ciągu zapytania. Na UserInformation.aspx stronie są wyświetlane informacje o wybranym użytkowniku i polach TextBoxes w celu zmiany hasła (zobacz Rysunek 9).

Po wprowadzeniu nowego hasła, potwierdzeniu go w drugim polu tekstowym i kliknięciu przycisku Aktualizuj użytkownika, następuje wycofanie i aspnet_Membership_SetPassword wywołanie procedury składowanej, aktualizowanie hasła użytkownika. Zachęcam tych czytelników zainteresowanych tą funkcją, aby lepiej zapoznać się z kodem i spróbować rozszerzyć funkcjonalność, aby uwzględnić wysłanie wiadomości e-mail do użytkownika, którego hasło zostało zmienione.

Administrator może zmienić hasło użytkownika

Rysunek 9. Administrator może zmienić hasło użytkownika (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Uwaga

Strona UserInformation.aspx działa obecnie tylko wtedy, gdy platforma członkostwa jest skonfigurowana do przechowywania haseł w formacie Wyczyść lub Skrót. Brakuje kodu do zaszyfrowania nowego hasła, chociaż zaproszono Cię do dodania tej funkcji. Zalecanym sposobem dodawania niezbędnego kodu jest użycie dekompilatora, takiego jak refleksora , w celu zbadania kodu źródłowego metod w programie .NET Framework. Zacznij od zbadania SqlMembershipProvider metody klasy ChangePassword . Jest to technika, która została użyta do pisania kodu w celu utworzenia skrótu hasła.

Podsumowanie

ASP.NET oferuje dwie kontrolki ułatwiające użytkownikom zarządzanie hasłem. Kontrolka PasswordRecovery jest przydatna dla tych, którzy zapomnieli swoje hasła. W zależności od konfiguracji struktury członkostwa użytkownik jest wysyłany pocztą e-mail do istniejącego hasła lub nowego, losowo wygenerowanego hasła. Kontrolka ChangePassword umożliwia użytkownikowi aktualizowanie hasła.

Podobnie jak kontrolki Login i CreateUserWizard, kontrolki PasswordRecovery i ChangePassword renderuje bogaty interfejs użytkownika bez konieczności pisania znaczników deklaratywnych lub wiersza kodu. Jeśli domyślny interfejs użytkownika nie spełnia Twoich potrzeb, możesz dostosować go za pomocą różnych właściwości stylu. Alternatywnie interfejsy kontrolek mogą być konwertowane na szablony w celu uzyskania jeszcze bardziej precyzyjnego stopnia kontroli. W tle te kontrolki używają interfejsu API członkostwa, wywołując MembershipUser metody i ChangePassword obiektuResetPassword.

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 24 godzinach. Scott można uzyskać na mitchell@4guysfromrolla.com stronie lub za pośrednictwem swojego bloga pod adresem http://ScottOnWriting.NET.

Specjalne podziękowania

Ta seria samouczków została omówiona przez wielu przydatnych recenzentów. Recenzenci z tego samouczka to Michael Emmings i Suchi Banerjee. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com