Udostępnij za pośrednictwem


Potwierdzenie konta i odzyskiwanie hasła za pomocą usługi ASP.NET Identity (C#)

Przed wykonaniem tego samouczka należy najpierw ukończyć tworzenie bezpiecznej aplikacji internetowej ASP.NET MVC 5 z logowaniem, potwierdzeniem wiadomości e-mail i resetowaniem hasła. Ten samouczek zawiera więcej szczegółów i pokaże, jak skonfigurować wiadomość e-mail na potrzeby potwierdzenia konta lokalnego i umożliwić użytkownikom resetowanie zapomnianego hasła w usłudze ASP.NET Identity.

Konto użytkownika lokalnego wymaga, aby użytkownik utworzył hasło dla konta, a hasło jest przechowywane (bezpiecznie) w aplikacji internetowej. ASP.NET Identity obsługuje również konta społecznościowe, które nie wymagają od użytkownika utworzenia hasła dla aplikacji. Konta społecznościowe używają innych firm (takich jak Google, Twitter, Facebook lub Microsoft) do uwierzytelniania użytkowników. W tym temacie omówiono następujące kwestie:

Nowi użytkownicy rejestrują alias poczty e-mail, który tworzy konto lokalne.

Obraz przedstawiający okno rejestracji konta

Wybranie przycisku Zarejestruj spowoduje wysłanie wiadomości e-mail z potwierdzeniem zawierającej token weryfikacji na swój adres e-mail.

Obraz przedstawiający potwierdzenie wysłania wiadomości e-mail

Użytkownik jest wysyłany pocztą e-mail z tokenem potwierdzenia dla swojego konta.

Obraz tokenu potwierdzenia

Wybranie linku potwierdza konto.

Obraz potwierdzający adres e-mail

Odzyskiwanie/resetowanie hasła

Użytkownicy lokalni, którzy zapominają o swoim haśle, mogą mieć token zabezpieczający wysłany na swoje konto e-mail, umożliwiając im zresetowanie hasła.

Obraz przedstawiający okno zapomnianego resetowania hasła

Użytkownik wkrótce otrzyma wiadomość e-mail z linkiem umożliwiającym zresetowanie hasła.

Obraz przedstawiający resetowanie wiadomości e-mail z hasłem
Wybranie linku spowoduje przejście do strony Resetowanie.

Obraz przedstawiający okno resetowania hasła użytkownika

Wybranie przycisku Resetuj potwierdzi zresetowanie hasła.

Obraz przedstawiający potwierdzenie resetowania hasła

Tworzenie aplikacji internetowej platformy ASP.NET

Rozpocznij od zainstalowania i uruchomienia programu Visual Studio 2017.

  1. Utwórz nowy projekt ASP.NET sieci Web i wybierz szablon MVC. Web Forms również obsługiwać usługę ASP.NET Identity, dzięki czemu możesz wykonać podobne kroki w aplikacji formularzy internetowych.

  2. Zmień uwierzytelnianie na Indywidualne konta użytkowników.

  3. Uruchom aplikację, wybierz link Zarejestruj i zarejestruj użytkownika. W tym momencie jedyną weryfikacją wiadomości e-mail jest atrybut [EmailAddress].

  4. W Eksploratorze serwera przejdź do pozycji Połączenia danych\DefaultConnection\Tables\AspNetUsers, kliknij prawym przyciskiem myszy i wybierz pozycję Otwórz definicję tabeli.

    Na poniższej ilustracji AspNetUsers przedstawiono schemat:

    Obraz przedstawiający schemat użytkowników sieci s p

  5. Kliknij prawym przyciskiem myszy tabelę AspNetUsers i wybierz polecenie Pokaż dane tabeli.

    Obraz przedstawiający dane tabeli

    W tym momencie wiadomość e-mail nie została potwierdzona.

Domyślnym magazynem danych dla tożsamości ASP.NET jest Entity Framework, ale można skonfigurować go tak, aby korzystał z innych magazynów danych i dodawać dodatkowe pola. Zobacz sekcję Dodatkowe zasoby na końcu tego samouczka.

Klasa uruchamiania OWIN (Startup.cs) jest wywoływana podczas uruchamiania aplikacji i wywołuje ConfigureAuth metodę w pliku App_Start\Startup.Auth.cs, który konfiguruje potok OWIN i inicjuje ASP.NET Identity. Sprawdź metodę ConfigureAuth . Każde CreatePerOwinContext wywołanie rejestruje wywołanie zwrotne (zapisane w obiekcie OwinContext), które będzie wywoływane raz na żądanie w celu utworzenia wystąpienia określonego typu. Można ustawić punkt przerwania w konstruktorze i metodzie każdego typu (ApplicationDbContext, ApplicationUserManager) i Create sprawdzić, czy są one wywoływane w każdym żądaniu. Wystąpienie i ApplicationDbContextApplicationUserManager jest przechowywane w kontekście OWIN, do którego można uzyskać dostęp w całej aplikacji. ASP.NET Tożsamość podłącza się do potoku OWIN za pośrednictwem oprogramowania pośredniczącego plików cookie. Aby uzyskać więcej informacji, zobacz Zarządzanie okresem istnienia żądania dla klasy UserManager w usłudze ASP.NET Identity.

Po zmianie profilu zabezpieczeń zostanie wygenerowana nowa sygnatura zabezpieczeń i zapisana w SecurityStamp polu tabeli AspNetUsers . Uwaga: SecurityStamp pole różni się od pliku cookie zabezpieczeń. Plik cookie zabezpieczeń nie jest przechowywany w AspNetUsers tabeli (ani nigdzie indziej w bazie danych tożsamości). Token pliku cookie zabezpieczeń jest podpisany samodzielnie przy użyciu interfejsu UserId, SecurityStampDPAPI i jest tworzony przy użyciu informacji o czasie wygaśnięcia i .

Oprogramowanie pośredniczące pliku cookie sprawdza plik cookie na każdym żądaniu. Metoda SecurityStampValidator w Startup klasie okresowo sprawdza bazę danych i sprawdza sygnaturę zabezpieczeń zgodnie z parametrem validateInterval. Dzieje się tak tylko co 30 minut (w naszym przykładzie), chyba że zmienisz profil zabezpieczeń. Wybrano interwał 30 minut, aby zminimalizować podróże do bazy danych. Aby uzyskać więcej informacji, zobacz mój samouczek dotyczący uwierzytelniania dwuskładnikowego .

Zgodnie z komentarzami w kodzie UseCookieAuthentication metoda obsługuje uwierzytelnianie plików cookie. Pole SecurityStamp i skojarzony kod zapewnia dodatkową warstwę zabezpieczeń aplikacji, po zmianie hasła zostanie wylogowany z zalogowanej przeglądarki. Metoda SecurityStampValidator.OnValidateIdentity umożliwia aplikacji zweryfikowanie tokenu zabezpieczającego podczas logowania użytkownika, który jest używany podczas zmiany hasła lub używania logowania zewnętrznego. Jest to konieczne, aby upewnić się, że wszystkie tokeny (pliki cookie) wygenerowane przy użyciu starego hasła są unieważniane. W przykładowym projekcie, jeśli zmienisz hasło użytkowników, zostanie wygenerowany nowy token dla użytkownika, wszystkie poprzednie tokeny zostaną unieważnione i SecurityStamp pole zostanie zaktualizowane.

System tożsamości umożliwia skonfigurowanie aplikacji tak, gdy profil zabezpieczeń użytkowników ulegnie zmianie (na przykład gdy użytkownik zmieni hasło lub zmieni skojarzone logowanie (na przykład z serwisu Facebook, Google, konta Microsoft itp.), użytkownik zostanie wylogowany ze wszystkich wystąpień przeglądarki. Na przykład na poniższej ilustracji przedstawiono przykładową aplikację logowania jednokrotnego , która umożliwia użytkownikowi wylogowanie się ze wszystkich wystąpień przeglądarki (w tym przypadku IE, Firefox i Chrome), wybierając jeden przycisk. Alternatywnie przykład umożliwia wylogowanie się tylko z określonego wystąpienia przeglądarki.

Obraz przedstawiający okno przykładowej aplikacji z logowaniem jednokrotnym

Przykładowa aplikacja logowania jednokrotnego pokazuje, jak usługa ASP.NET Identity umożliwia ponowne generowanie tokenu zabezpieczającego. Jest to konieczne, aby upewnić się, że wszystkie tokeny (pliki cookie) wygenerowane przy użyciu starego hasła są unieważniane. Ta funkcja zapewnia dodatkową warstwę zabezpieczeń aplikacji; Po zmianie hasła użytkownik zostanie wylogowany, w którym zalogowano się do tej aplikacji.

Plik App_Start\IdentityConfig.cs zawiera ApplicationUserManagerEmailService klasy i SmsService . Klasy EmailService i SmsService implementują IIdentityMessageService interfejs, dzięki czemu w każdej klasie istnieją typowe metody konfigurowania poczty e-mail i wiadomości SMS. Chociaż w tym samouczku pokazano tylko sposób dodawania powiadomień e-mail za pośrednictwem usługi SendGrid, można wysyłać wiadomości e-mail przy użyciu protokołu SMTP i innych mechanizmów.

Klasa Startup zawiera również płytę kotłową, aby dodać logowania społecznościowe (Facebook, Twitter itp.), zobacz mój samouczek MVC 5 App with Facebook, Twitter, LinkedIn i Google OAuth2 Sign-on , aby uzyskać więcej informacji.

Sprawdź klasę ApplicationUserManager , która zawiera informacje o tożsamości użytkowników i konfiguruje następujące funkcje:

  • Wymagania dotyczące siły hasła.
  • Blokada użytkownika (próby i czas).
  • Uwierzytelnianie dwuskładnikowe (2FA). Omówię 2FA i SMS w innym samouczku.
  • Podłączanie usług poczty e-mail i wiadomości SMS. (Omówię wiadomość SMS w innym samouczku).

Klasa ApplicationUserManager pochodzi z klasy ogólnej UserManager<ApplicationUser> . ApplicationUser pochodzi od identityUser. IdentityUser pochodzi z klasy ogólnej IdentityUser :

//     Default EntityFramework IUser implementation
public class IdentityUser<TKey, TLogin, TRole, TClaim> : IUser<TKey>
   where TLogin : IdentityUserLogin<TKey>
   where TRole : IdentityUserRole<TKey>
   where TClaim : IdentityUserClaim<TKey>
{
   public IdentityUser()
   {
      Claims = new List<TClaim>();
      Roles = new List<TRole>();
      Logins = new List<TLogin>();
   }

   ///     User ID (Primary Key)
   public virtual TKey Id { get; set; }

   public virtual string Email { get; set; }
   public virtual bool EmailConfirmed { get; set; }

   public virtual string PasswordHash { get; set; }

   ///     A random value that should change whenever a users credentials have changed (password changed, login removed)
   public virtual string SecurityStamp { get; set; }

   public virtual string PhoneNumber { get; set; }
   public virtual bool PhoneNumberConfirmed { get; set; }

   public virtual bool TwoFactorEnabled { get; set; }

   ///     DateTime in UTC when lockout ends, any time in the past is considered not locked out.
   public virtual DateTime? LockoutEndDateUtc { get; set; }

   public virtual bool LockoutEnabled { get; set; }

   ///     Used to record failures for the purposes of lockout
   public virtual int AccessFailedCount { get; set; }
   
   ///     Navigation property for user roles
   public virtual ICollection<TRole> Roles { get; private set; }

   ///     Navigation property for user claims
   public virtual ICollection<TClaim> Claims { get; private set; }

   ///     Navigation property for user logins
   public virtual ICollection<TLogin> Logins { get; private set; }
   
   public virtual string UserName { get; set; }
}

Powyższe właściwości pokrywają się z właściwościami w AspNetUsers tabeli pokazanymi powyżej.

Ogólne argumenty na IUser platformie umożliwiają uzyskiwanie klasy przy użyciu różnych typów klucza podstawowego. Zobacz przykład ChangePK , który pokazuje, jak zmienić klucz podstawowy z ciągu na int lub GUID.

ApplicationUser

ApplicationUser (public class ApplicationUserManager : UserManager<ApplicationUser>) jest definiowana w pliku Models\IdentityModels.cs jako:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(
        UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in 
       //   CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, 
    DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

Wyróżniony kod powyżej generuje wartość ClaimsIdentity. ASP.NET Tożsamość i Uwierzytelnianie plików cookie OWIN są oparte na oświadczeniach, dlatego platforma wymaga, aby aplikacja wygenerowała element ClaimsIdentity dla użytkownika. ClaimsIdentity zawiera informacje o wszystkich oświadczeniach użytkownika, takich jak nazwa użytkownika, wiek i role, do których należy użytkownik. Możesz również dodać więcej oświadczeń dla użytkownika na tym etapie.

Metoda OWIN AuthenticationManager.SignIn przekazuje element ClaimsIdentity i loguje się do użytkownika:

private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    AuthenticationManager.SignIn(new AuthenticationProperties(){
       IsPersistent = isPersistent }, 
       await user.GenerateUserIdentityAsync(UserManager));
}

Aplikacja MVC 5 z aplikacjami Facebook, Twitter, LinkedIn i Google OAuth2 pokazuje, jak dodać dodatkowe właściwości do ApplicationUser klasy.

potwierdzenie Email

Dobrym pomysłem jest potwierdzenie, że nowy użytkownik zarejestruje się przy użyciu nowego użytkownika, aby sprawdzić, czy nie personifikuje innego użytkownika (oznacza to, że nie zarejestrował się w wiadomości e-mail innej osoby). Załóżmy, że masz forum dyskusyjne, chcesz uniemożliwić "bob@example.com" rejestrację jako "joe@contoso.com". Bez potwierdzenia "joe@contoso.com" wiadomości e-mail niepożądane wiadomości e-mail z aplikacji. Załóżmy, że Bob przypadkowo zarejestrował się jako "bib@example.com" i nie zauważył go, nie będzie mógł odzyskać hasła, ponieważ aplikacja nie ma poprawnej poczty e-mail. Email potwierdzenie zapewnia tylko ograniczoną ochronę przed botami i nie zapewnia ochrony przed określonymi spamerami, mają one wiele działających aliasów poczty e-mail, których mogą używać do rejestrowania. W poniższym przykładzie użytkownik nie będzie mógł zmienić swojego hasła do momentu potwierdzenia konta (wybierając przez nich link potwierdzenia odebrany na koncie e-mail, z którego się zarejestrował). Ten przepływ pracy można zastosować do innych scenariuszy, na przykład wysyłając link w celu potwierdzenia i zresetowania hasła na nowych kontach utworzonych przez administratora, wysyłając użytkownikowi wiadomość e-mail po zmianie profilu itd. Zazwyczaj chcesz uniemożliwić nowym użytkownikom publikowanie wszelkich danych w witrynie sieci Web przed potwierdzeniem ich za pomocą poczty e-mail, wiadomości SMS lub innego mechanizmu.

Tworzenie bardziej kompletnego przykładu

W tej sekcji użyjesz narzędzia NuGet, aby pobrać bardziej kompletny przykład, z którym będziemy pracować.

  1. Utwórz nowy pusty projekt ASP.NET sieci Web.

  2. W konsoli Menedżera pakietów wprowadź następujące polecenia:

    Install-Package SendGrid
    Install-Package -Prerelease Microsoft.AspNet.Identity.Samples
    

    W tym samouczku użyjemy usługi SendGrid do wysyłania wiadomości e-mail. Pakiet Identity.Samples instaluje kod, z którym będziemy pracować.

  3. Ustaw projekt na użycie protokołu SSL.

  4. Przetestuj tworzenie konta lokalnego, uruchamiając aplikację, wybierając link Zarejestruj i publikując formularz rejestracji.

  5. Wybierz link demonstracyjny wiadomości e-mail, który symuluje potwierdzenie wiadomości e-mail.

  6. Usuń kod potwierdzenia linku demonstracyjnego wiadomości e-mail z przykładu ( ViewBag.Link kod w kontrolerze konta. DisplayEmail Zobacz metody i ForgotPasswordConfirmation akcji i widoki razor ).

Ostrzeżenie

Jeśli zmienisz dowolne ustawienia zabezpieczeń w tym przykładzie, aplikacje produkcyjne będą musiały przejść inspekcję zabezpieczeń, która jawnie wywołuje wprowadzone zmiany.

Sprawdzanie kodu w pliku App_Start\IdentityConfig.cs

W przykładzie pokazano, jak utworzyć konto i dodać je do roli Administracja. W przykładzie należy zastąpić wiadomość e-mail pocztą e-mail, której będziesz używać dla konta administratora. Najprostszym sposobem na utworzenie konta administratora jest programowe w metodzie Seed . Mamy nadzieję, że w przyszłości będziemy mieli narzędzie, które umożliwi tworzenie i administrowanie użytkownikami i rolami. Przykładowy kod umożliwia tworzenie użytkowników i ról oraz zarządzanie nimi, ale musisz najpierw mieć konto administratorów do uruchamiania ról i stron administratorów użytkowników. W tym przykładzie konto administratora jest tworzone podczas rozmieszczania bazy danych.

Zmień hasło i zmień nazwę na konto, na którym można otrzymywać powiadomienia e-mail.

Ostrzeżenie

Zabezpieczenia — nigdy nie przechowuj poufnych danych w kodzie źródłowym.

Jak wspomniano wcześniej, app.CreatePerOwinContext wywołanie w klasie uruchamiania dodaje wywołania zwrotne do Create metody zawartości bazy danych aplikacji, menedżera użytkowników i klas menedżera ról. Potok OWIN wywołuje metodę Create dla każdego żądania i przechowuje kontekst dla każdej klasy. Kontroler konta uwidacznia menedżera użytkowników z kontekstu HTTP (który zawiera kontekst OWIN):

public ApplicationUserManager UserManager
{
    get
    {
        return _userManager ?? 
    HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
    }
    private set
    {
        _userManager = value;
    }
}

Gdy użytkownik rejestruje konto lokalne, metoda jest wywoływana HTTP Post Register :

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
        var result = await UserManager.CreateAsync(user, model.Password);
        if (result.Succeeded)
        {
            var code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
            var callbackUrl = Url.Action(
               "ConfirmEmail", "Account", 
               new { userId = user.Id, code = code }, 
               protocol: Request.Url.Scheme);

            await UserManager.SendEmailAsync(user.Id, 
               "Confirm your account", 
               "Please confirm your account by clicking this link: <a href=\"" 
                                               + callbackUrl + "\">link</a>");
            // ViewBag.Link = callbackUrl;   // Used only for initial demo.
            return View("DisplayEmail");
        }
        AddErrors(result);
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

Powyższy kod używa danych modelu do utworzenia nowego konta użytkownika przy użyciu wprowadzonego adresu e-mail i hasła. Jeśli alias wiadomości e-mail znajduje się w magazynie danych, tworzenie konta kończy się niepowodzeniem i zostanie ponownie wyświetlony formularz. Metoda GenerateEmailConfirmationTokenAsync tworzy bezpieczny token potwierdzenia i przechowuje go w magazynie danych usługi ASP.NET Identity. Metoda Url.Action tworzy link zawierający UserId token potwierdzenia i. Ten link jest następnie wysyłany do użytkownika, użytkownik może wybrać link w swojej aplikacji poczty e-mail, aby potwierdzić swoje konto.

Konfigurowanie potwierdzenia wiadomości e-mail

Przejdź do strony rejestracji usługi SendGrid i zarejestruj się w celu uzyskania bezpłatnego konta. Dodaj kod podobny do poniższego, aby skonfigurować usługę SendGrid:

public class EmailService : IIdentityMessageService
{
   public Task SendAsync(IdentityMessage message)
   {
      return configSendGridasync(message);
   }

   private Task configSendGridasync(IdentityMessage message)
   {
      var myMessage = new SendGridMessage();
      myMessage.AddTo(message.Destination);
      myMessage.From = new System.Net.Mail.MailAddress(
                          "Joe@contoso.com", "Joe S.");
      myMessage.Subject = message.Subject;
      myMessage.Text = message.Body;
      myMessage.Html = message.Body;

      var credentials = new NetworkCredential(
                 ConfigurationManager.AppSettings["mailAccount"],
                 ConfigurationManager.AppSettings["mailPassword"]
                 );

      // Create a Web transport for sending email.
      var transportWeb = new Web(credentials);

      // Send the email.
      if (transportWeb != null)
      {
         return transportWeb.DeliverAsync(myMessage);
      }
      else
      {
         return Task.FromResult(0);
      }
   }
}

Uwaga

Email klienci często akceptują tylko wiadomości SMS (bez kodu HTML). Należy podać komunikat w tekście i kodzie HTML. W powyższym przykładzie sendGrid jest to wykonywane przy użyciu kodu i myMessage.Html pokazanego myMessage.Text powyżej.

Poniższy kod pokazuje, jak wysyłać wiadomości e-mail przy użyciu klasy MailMessage , w której message.Body zwracany jest tylko link.

void sendMail(Message message)
{
#region formatter
   string text = string.Format("Please click on this link to {0}: {1}", message.Subject, message.Body);
   string html = "Please confirm your account by clicking this link: <a href=\"" + message.Body + "\">link</a><br/>";

   html += HttpUtility.HtmlEncode(@"Or click on the copy the following link on the browser:" + message.Body);
#endregion

   MailMessage msg = new MailMessage();
   msg.From = new MailAddress("joe@contoso.com");
   msg.To.Add(new MailAddress(message.Destination));
   msg.Subject = message.Subject;
   msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(text, null, MediaTypeNames.Text.Plain));
   msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(html, null, MediaTypeNames.Text.Html));

   SmtpClient smtpClient = new SmtpClient("smtp.gmail.com", Convert.ToInt32(587));
   System.Net.NetworkCredential credentials = new System.Net.NetworkCredential("joe@contoso.com", "XXXXXX");
   smtpClient.Credentials = credentials;
   smtpClient.EnableSsl = true;
   smtpClient.Send(msg);
}

Ostrzeżenie

Zabezpieczenia — nigdy nie przechowuj poufnych danych w kodzie źródłowym. Konto i poświadczenia są przechowywane w aplikacjiSetting. Na platformie Azure można bezpiecznie przechowywać te wartości na karcie Konfigurowanie w Azure Portal. Zobacz Najlepsze rozwiązania dotyczące wdrażania haseł i innych poufnych danych w ASP.NET i na platformie Azure.

Wprowadź poświadczenia usługi SendGrid, uruchom aplikację, zarejestruj się za pomocą aliasu poczty e-mail, aby wybrać link potwierdzania w wiadomości e-mail. Aby dowiedzieć się, jak to zrobić za pomocą konta e-mail Outlook.com , zobacz Konfiguracja protokołu SMTP języka C# johna Attena dla Outlook.Com hosta SMTP i jegoASP.NET Identity 2.0: Konfigurowanie weryfikacji konta i Two-Factor postów autoryzacji .

Gdy użytkownik wybierze przycisk Zarejestruj , zostanie wysłana wiadomość e-mail z potwierdzeniem zawierającą token weryfikacji na swój adres e-mail.

Obraz przedstawiający okno potwierdzenia wysłanego wiadomości e-mail

Użytkownik jest wysyłany pocztą e-mail z tokenem potwierdzenia dla swojego konta.

Obraz odebranej wiadomości e-mail

Analizowanie kodu

Poniższy kod przedstawia metodę POST ForgotPassword .

public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = await UserManager.FindByNameAsync(model.Email);
        if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
        {
            // Don't reveal that the user does not exist or is not confirmed
            return View("ForgotPasswordConfirmation");
        }

        var code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
        var callbackUrl = Url.Action("ResetPassword", "Account", 
    new { UserId = user.Id, code = code }, protocol: Request.Url.Scheme);
        await UserManager.SendEmailAsync(user.Id, "Reset Password", 
    "Please reset your password by clicking here: <a href=\"" + callbackUrl + "\">link</a>");        
        return View("ForgotPasswordConfirmation");
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

Metoda nie powiedzie się dyskretnie, jeśli wiadomość e-mail użytkownika nie została potwierdzona. Jeśli dla nieprawidłowego adresu e-mail wysłano błąd, złośliwi użytkownicy mogą użyć tych informacji do znalezienia prawidłowego identyfikatora użytkownika (aliasów e-mail) do ataku.

Poniższy kod przedstawia metodę ConfirmEmail w kontrolerze konta, która jest wywoływana, gdy użytkownik wybierze link potwierdzenia w wiadomości e-mail wysłanej do nich:

public async Task<ActionResult> ConfirmEmail(string userId, string code)
{
    if (userId == null || code == null)
    {
        return View("Error");
    }
    var result = await UserManager.ConfirmEmailAsync(userId, code);
    if (result.Succeeded)
    {
        return View("ConfirmEmail");
    }
    AddErrors(result);
    return View();
}

Po użyciu zapomnianego tokenu hasła zostanie on unieważniony. Następująca zmiana kodu w metodzie Create (w pliku App_Start\IdentityConfig.cs ) ustawia tokeny do wygaśnięcia w ciągu 3 godzin.

if (dataProtectionProvider != null)
 {
    manager.UserTokenProvider =
       new DataProtectorTokenProvider<ApplicationUser>
          (dataProtectionProvider.Create("ASP.NET Identity"))
          {                    
             TokenLifespan = TimeSpan.FromHours(3)
          };
 }

W powyższym kodzie zapomniane hasło i tokeny potwierdzenia wiadomości e-mail wygasają w ciągu 3 godzin. Wartość domyślna TokenLifespan to jeden dzień.

Poniższy kod przedstawia metodę potwierdzenia wiadomości e-mail:

// GET: /Account/ConfirmEmail
[AllowAnonymous]
public async Task<ActionResult> ConfirmEmail(string userId, string code)
{
   if (userId == null || code == null)
   {
      return View("Error");
   }
   IdentityResult result;
   try
   {
      result = await UserManager.ConfirmEmailAsync(userId, code);
   }
   catch (InvalidOperationException ioe)
   {
      // ConfirmEmailAsync throws when the userId is not found.
      ViewBag.errorMessage = ioe.Message;
      return View("Error");
   }

   if (result.Succeeded)
   {
      return View();
   }

   // If we got this far, something failed.
   AddErrors(result);
   ViewBag.errorMessage = "ConfirmEmail failed";
   return View("Error");
}

Aby zapewnić bezpieczeństwo aplikacji, usługa ASP.NET Identity obsługuje uwierzytelnianie Two-Factor (2FA). Zobacz ASP.NET Identity 2.0: Konfigurowanie weryfikacji konta i Two-Factor autoryzacji przez Johna Attena. Mimo że można ustawić blokadę konta w przypadku niepowodzeń prób logowania, takie podejście sprawia, że logowanie jest podatne na blokady systemu DOS . Zalecamy używanie blokady konta tylko w przypadku uwierzytelniania 2FA.

Dodatkowe zasoby