Freigeben über


Kontobestätigung und Kennwortwiederherstellung mit ASP.NET Identity (C#)

Bevor Sie dieses Tutorial durchführen, sollten Sie zunächst Erstellen einer sicheren ASP.NET MVC 5 Web-App mit Anmeldung, E-Mail-Bestätigung und Zurücksetzen des Kennworts erledigen. Dieses Lernprogramm enthält weitere Details und zeigt Ihnen, wie Sie E-Mails für die Bestätigung des lokalen Kontos einrichten und Benutzern das Zurücksetzen ihres vergessenen Kennworts in ASP.NET Identität ermöglichen.

Ein lokales Benutzerkonto erfordert, dass der Benutzer ein Kennwort für das Konto erstellt und dieses Kennwort (sicher) in der Web-App gespeichert wird. ASP.NET Identity unterstützt auch Konten für soziale Netzwerke, bei denen der Benutzer kein Kennwort für die App erstellen muss. Soziale Netzwerkkonten verwenden einen Drittanbieter (z. B. Google, Twitter, Facebook oder Microsoft), um Benutzer zu authentifizieren. In diesem Thema geht es um Folgendes:

Neue Benutzer registrieren ihren E-Mail-Alias, wodurch ein lokales Konto erstellt wird.

Bild des Kontoregisterfensters

Wenn Sie die Schaltfläche "Registrieren" auswählen, wird eine Bestätigungs-E-Mail mit einem Überprüfungstoken an ihre E-Mail-Adresse gesendet.

Bild der E-Mail-Bestätigung

Der Benutzer wird eine E-Mail mit einem Bestätigungstoken für sein Konto gesendet.

Bild des Bestätigungs-Tokens

Wenn Sie den Link auswählen, wird das Konto bestätigt.

Bild, das die E-Mail-Adresse bestätigt

Passwortwiederherstellung/Zurücksetzen

Lokale Benutzer, die ihr Kennwort vergessen, können ein Sicherheitstoken an ihr E-Mail-Konto senden, sodass sie ihr Kennwort zurücksetzen können.

Bild des Fensters zum Zurücksetzen des Kennworts

Der Benutzer erhält bald eine E-Mail mit einem Link, über den er sein Kennwort zurücksetzen kann.

Bild, das eine E-Mail zum Zurücksetzen des Passworts zeigt
Wenn Sie den Link anklicken, gelangen Sie auf die Seite Zurücksetzen.

Bild des Fensters zum Zurücksetzen des Kennworts des Benutzers

Wenn Sie die Schaltfläche Zurücksetzen anklicken, wird bestätigt, dass das Kennwort zurückgesetzt wurde.

Bild mit der Bestätigung der Zurücksetzung des Kennworts

Erstellen einer ASP.NET Web-App

Beginnen Sie, indem Sie Visual Studio 2017installieren und ausführen.

  1. Erstellen Sie ein neues ASP.NET Webprojekt, und wählen Sie die MVC-Vorlage aus. Web Forms unterstützen auch ASP.NET Identity, sodass Sie ähnliche Schritte in einer Webformular-App ausführen können.

  2. Ändern Sie die Authentifizierung auf Individuelle Benutzerkonten.

  3. Führen Sie die App aus, wählen Sie den Link Registrieren und registrieren Sie einen Benutzer. Die einzige Validierung der E-Mail erfolgt an diesem Punkt mit dem [EmailAddress] Attribut.

  4. Navigieren Sie im Server Explorer zu Data Connections\DefaultConnection\Tables\AspNetUsers, klicken Sie mit der rechten Maustaste und wählen Sie Tabellendefinition öffnen.

    Das folgende Bild zeigt das AspNetUsers Schema:

    Bild mit dem Schema ASP.Net Benutzer

  5. Klicken Sie mit der rechten Maustaste auf die Tabelle AspNetUsers und wählen Sie Tabellendaten anzeigen.

    Bild zeigt Tabellendaten

    An diesem Punkt wurde die E-Mail nicht bestätigt.

Der Standarddatenspeicher für ASP.NET Identity ist Entity Framework, sie kann jedoch so konfiguriert werden, dass andere Datenspeicher verwendet und zusätzliche Felder hinzugefügt werden. Siehe den Abschnitt Zusätzliche Ressourcen am Ende dieses Tutorials.

Die OWIN-Startklasse ( Startup.cs ) wird aufgerufen, wenn die App startet und die ConfigureAuth-Methode in App_Start\Startup.Auth.csaufruft, die die OWIN-Pipeline konfiguriert und ASP.NET Identity initialisiert. Untersuchen Sie die Methode ConfigureAuth. Jeder CreatePerOwinContext-Aufruf registriert einen Callback (gespeichert in OwinContext), der einmal pro Anfrage aufgerufen wird, um eine Instanz des angegebenen Typs zu erstellen. Sie können im Konstruktor und in der Create-Methode jedes Typs (ApplicationDbContext, ApplicationUserManager) einen Haltepunkt festlegen und überprüfen, ob sie bei jeder Anfrage aufgerufen werden. Eine Instanz von ApplicationDbContext und ApplicationUserManager wird im OWIN-Kontext gespeichert, auf die in der gesamten Anwendung zugegriffen werden kann. ASP.NET Identity ist über eine Cookie-Middleware mit der OWIN Pipeline verbunden. Weitere Informationen finden Sie unter Verwaltung der Lebensdauer pro Anfrage für die Klasse UserManager in ASP.NET Identity.

Wenn Sie Ihr Sicherheitsprofil ändern, wird ein neuer Sicherheitsstempel generiert und im Feld SecurityStamp der AspNetUsers Tabelle gespeichert. Beachten Sie, dass sich das Feld SecurityStamp vom Sicherheitscookie unterscheidet. Das Sicherheits-Cookie wird nicht in der AspNetUsers-Tabelle (oder an einer anderen Stelle in der Identitätsdatenbank) gespeichert. Das Token für den Sicherheits-Cookie wird mit Hilfe von DPAPI selbst signiert und mit den Informationen UserId, SecurityStampund der Verfallszeit erstellt.

Die Cookie-Middleware überprüft das Cookie auf jeder Anforderung. Die SecurityStampValidator-Methode in der Startup-Klasse greift auf die DB zu und überprüft den Sicherheitsstempel in regelmäßigen Abständen, wie mit validateInterval angegeben. Dies geschieht nur alle 30 Minuten (in unserem Beispiel), es sei denn, Sie ändern Ihr Sicherheitsprofil. Das 30-Minuten-Intervall wurde ausgewählt, um Reisen in die Datenbank zu minimieren. Weitere Informationen finden Sie in meinem Lernprogramm zur zweistufigen Authentifizierung.

Gemäß den Kommentaren im Code unterstützt die UseCookieAuthentication-Methode die Cookieauthentifizierung. Das SecurityStamp Feld und der zugehörige Code bieten Ihrer App eine zusätzliche Sicherheitsebene, wenn Sie Ihr Kennwort ändern, werden Sie vom Browser abgemeldet, mit dem Sie angemeldet sind. Mit der SecurityStampValidator.OnValidateIdentity-Methode kann die App das Sicherheitstoken überprüfen, wenn sich der Benutzer anmeldet, der verwendet wird, wenn Sie ein Kennwort ändern oder die externe Anmeldung verwenden. Dies ist erforderlich, um sicherzustellen, dass alle mit dem alten Kennwort generierten Token (Cookies) ungültig sind. Wenn Sie im Beispielprojekt das Benutzerkennwort ändern, wird ein neues Token für den Benutzer generiert, werden alle vorherigen Token ungültig, und das Feld SecurityStamp wird aktualisiert.

Mit dem Identitätssystem können Sie Ihre App so konfigurieren, wenn sich das Sicherheitsprofil der Benutzer ändert (z. B. wenn der Benutzer sein Kennwort oder die zugehörige Anmeldung ändert (z. B. von Facebook, Google, Microsoft-Konto usw.), wird der Benutzer von allen Browserinstanzen abgemeldet. Das folgende Bild zeigt zum Beispiel die App Single signout example, die dem Benutzenden die Möglichkeit bietet, sich mit einer Schaltfläche von allen Instanzen des Browsers (in diesem Fall IE, Firefox und Chrome) abzumelden. Alternativ können Sie sich im Beispiel nur von einer bestimmten Browserinstanz abmelden.

Bild mit dem Fenster der Beispiel App

Die Beispiel-App Single Signout zeigt, wie ASP.NET Identity Ihnen die Möglichkeit bietet, das Sicherheitstoken zu regenerieren. Dies ist erforderlich, um sicherzustellen, dass alle mit dem alten Kennwort generierten Token (Cookies) ungültig sind. Dieses Feature bietet Ihrer Anwendung eine zusätzliche Sicherheitsebene. Wenn Sie Ihr Kennwort ändern, werden Sie von überall abgemeldet, wo Sie in dieser Anwendung eingeloggt waren.

Die Datei App_Start\IdentityConfig.cs enthält die Klassen ApplicationUserManager, EmailService und SmsService. Die EmailService- und SmsService Klassen implementieren jeweils die IIdentityMessageService Schnittstelle, sodass Sie in jeder Klasse allgemeine Methoden zum Konfigurieren von E-Mails und SMS haben. Obwohl in diesem Lernprogramm nur gezeigt wird, wie Sie E-Mail-Benachrichtigungen über SendGrid-hinzufügen, können Sie E-Mails mithilfe von SMTP und anderen Mechanismen senden.

Die Startup-Klasse enthält auch eine Boiler-Plate, um Anmeldungen über soziale Netzwerke (Facebook, Twitter, usw.) hinzuzufügen. Weitere Informationen finden Sie in meinem Tutorial MVC 5 App mit Facebook, Twitter, LinkedIn und Google OAuth2 Sign-on.

Überprüfen Sie die ApplicationUserManager Klasse, die die Benutzeridentitätsinformationen enthält, und konfigurieren Sie die folgenden Features:

  • Anforderungen an die Kennwortstärke.
  • Sperren von Benutzern (Versuche und Zeit).
  • Zweistufige Authentifizierung (2FA). Ich werde 2FA und SMS in einem anderen Tutorial behandeln.
  • Einbinden der Dienste E-Mail und SMS. (Ich werde SMS in einem anderen Tutorial behandeln).

Die ApplicationUserManager Klasse wird von der generischen UserManager<ApplicationUser> Klasse abgeleitet. ApplicationUser leitet sich von IdentityUser ab. IdentityUser wird von der generischen Klasse IdentityUser abgeleitet.

//     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; }
}

Die oben aufgeführten Eigenschaften stimmen mit den Eigenschaften in der AspNetUsers Tabelle überein, wie oben gezeigt.

Generische Parameter für IUser ermöglichen es Ihnen, eine Klasse mit verschiedenen Typen für den Primärschlüssel abzuleiten. Sehen Sie sich das Beispiel ChangePK an, das zeigt, wie Sie die primäre Zeichenfolge von Zeichenfolge in int oder GUID ändern.

ApplicationUser

ApplicationUser (public class ApplicationUserManager : UserManager<ApplicationUser>) wird in Models\IdentityModels.cs wie folgt definiert:

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;
    }
}

Der oben hervorgehobene Code generiert eine ClaimsIdentity. Da ASP.NET Identity und die OWIN-Cookie-Authentifizierung anspruchsbasiert sind, erfordert das Framework daher, dass die App eine ClaimsIdentity für den Benutzer generiert. ClaimsIdentity enthält Informationen über alle Ansprüche des Benutzers, wie z. B. den Namen des Benutzers, sein Alter und die Rollen, denen der Benutzer angehört. Sie können in dieser Phase auch weitere Ansprüche für den Benutzer hinzufügen.

Die OWIN AuthenticationManager.SignIn Methode übergibt die ClaimsIdentity und meldet den Benutzer an:

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

MVC 5 App mit Facebook, Twitter, LinkedIn und Google OAuth2 Sign-on zeigt, wie Sie der Klasse ApplicationUser zusätzliche Eigenschaften hinzufügen können.

E-Mail-Bestätigung

Es empfiehlt sich, die E-Mail zu bestätigen, mit der sich ein neuer Benutzer registriert, um zu überprüfen, ob er sich nicht als jemand anderes ausgibt (d. h., er hat sich nicht mit der E-Mail einer anderen Person registriert). Angenommen, Sie hätten ein Diskussionsforum, dann würden Sie verhindern wollen, dass sich "bob@example.com" als "joe@contoso.com" anmeldet. Ohne E-Mail-Bestätigung könnte "joe@contoso.com" unerwünschte E-Mails von Ihrer App erhalten. Angenommen, Bob hätte sich versehentlich als "bib@example.com" registriert und es nicht bemerkt, könnte er das Kennwort nicht wiederherstellen, weil die App nicht über seine korrekte E-Mail verfügt. Die E-Mail-Bestätigung bietet nur eingeschränkten Schutz vor Bots und bietet keinen Schutz vor bestimmten Spammern, sie haben viele funktionierende E-Mail-Aliase, die sie zum Registrieren verwenden können. Im folgenden Beispiel kann der Benutzer sein Kennwort erst ändern, wenn sein Konto bestätigt wurde (indem er einen Bestätigungslink aus dem E-Mail-Konto auswählt, bei dem er sich registriert hat.) Sie können diesen Arbeitsablauf auf andere Szenarien anwenden, z. B. das Senden eines Links zum Bestätigen und Zurücksetzen des Kennworts für neue Konten, die vom Administrator erstellt wurden, dem Benutzer eine E-Mail senden, wenn er sein Profil geändert hat usw. Im Allgemeinen möchten Sie verhindern, dass neue Benutzer Daten auf Ihrer Website veröffentlichen, bevor sie per E-Mail, SMS oder einem anderen Mechanismus bestätigt wurden.

Ein vollständigeres Beispiel erstellen

In diesem Abschnitt verwenden Sie NuGet, um ein ausführlicheres Beispiel herunterzuladen, mit dem wir arbeiten werden.

  1. Erstellen Sie ein neues leeres ASP.NET Webprojekt.

  2. Geben Sie in der Paket-Manager-Konsole die folgenden Befehle ein:

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

    In diesem Tutorial verwenden wir SendGrid, um E-Mails zu senden. Das Identity.Samples Paket installiert den Code, mit dem wir arbeiten werden.

  3. Stellen Sie das Projekt so ein, dass SSLverwendet wird.

  4. Testen Sie die Erstellung eines lokalen Kontos, indem Sie die App ausführen, auf den Registrieren Link klicken und das Registrierungsformular abschicken.

  5. Wählen Sie den Demo-E-Mail-Link aus, der die E-Mail-Bestätigung simuliert.

  6. Entfernen Sie den Code zur Bestätigung des Demo-E-Mail-Links aus dem Beispiel (Der ViewBag.Link Code in der Kontosteuerung. Siehe die DisplayEmail und ForgotPasswordConfirmation Aktionsmethoden und Razor Views ).

Warnung

Wenn Sie eine der Sicherheitseinstellungen in diesem Beispiel ändern, müssen Produktions-Apps einer Sicherheitsüberwachung unterzogen werden, die die vorgenommenen Änderungen explizit aufruft.

Untersuche den Code in App_Start\IdentityConfig.cs

Das Beispiel zeigt, wie Sie ein Konto erstellen und es der Rolle Admin hinzufügen. Sie sollten die E-Mail im Beispiel durch die E-Mail ersetzen, die Sie für das Administratorkonto verwenden. Derzeit ist die einfachste Methode zum Erstellen eines Administratorkontos, dies programmgesteuert in der Seed-Methode zu tun. Wir hoffen, in Zukunft ein Tool zu haben, mit dem Sie Benutzer und Rollen erstellen und verwalten können. Mit dem Beispielcode können Sie Benutzer und Rollen erstellen und verwalten. Sie müssen jedoch zuerst über ein Administratorkonto verfügen, um die Rollen und Benutzeradministratorseiten auszuführen. In diesem Beispiel wird das Administratorkonto erstellt, wenn die Datenbank initialisiert wird.

Ändern Sie das Kennwort und den Namen in einem Konto, bei dem Sie E-Mail-Benachrichtigungen erhalten können.

Warnung

Sicherheit – Speichern Sie niemals vertrauliche Daten in Ihrem Quellcode.

Wie bereits erwähnt, fügt der app.CreatePerOwinContext-Aufruf in der Startup-Klasse Callbacks zur Create-Methode der App DB Content, User Manager und Role Manager Klassen hinzu. Die OWIN-Pipeline ruft die Create-Methode für diese Klassen für jede Anforderung auf und speichert den Kontext für jede Klasse. Der Account Controller stellt den Benutzer Manager aus dem HTTP-Kontext (der den OWIN-Kontext enthält) zur Verfügung:

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

Wenn ein Benutzer ein lokales Konto registriert, wird die HTTP Post Register-Methode aufgerufen:

[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);
}

Der obige Code verwendet die Modelldaten, um ein neues Benutzerkonto mit der eingegebenen E-Mail und dem eingegebenen Kennwort zu erstellen. Wenn sich der E-Mail-Alias im Datenspeicher befindet, schlägt die Kontoerstellung fehl, und das Formular wird erneut angezeigt. Die GenerateEmailConfirmationTokenAsync-Methode erstellt ein sicheres Bestätigungstoken und speichert es im ASP.NET Identitätsdatenspeicher. Die Methode Url.Action erstellt einen Link, der das UserId und das Bestätigungs-Token enthält. Dieser Link wird dann an den Benutzer per E-Mail gesendet, der Benutzer kann den Link in seiner E-Mail-App auswählen, um sein Konto zu bestätigen.

Einrichten der E-Mail-Bestätigung

Wechseln Sie zur SendGrid-Registrierungsseite, und registrieren Sie sich für ein kostenloses Konto. Fügen Sie Code wie folgt hinzu, um SendGrid zu konfigurieren:

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);
      }
   }
}

Anmerkung

E-Mail-Clients akzeptieren häufig nur Textnachrichten (kein HTML). Sie sollten die Nachricht in Text und HTML angeben. Im obigen SendGrid-Beispiel erfolgt dies mit dem oben gezeigten myMessage.Text und myMessage.Html Code.

Der folgende Code zeigt, wie E-Mails mithilfe der MailMessage- Klasse gesendet werden, in der message.Body nur den Link zurückgibt.

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);
}

Warnung

Sicherheit – Speichern Sie niemals vertrauliche Daten in Ihrem Quellcode. Das Konto und die Anmeldeinformationen werden im appSetting gespeichert. Auf Azure können Sie diese Werte sicher auf der Registerkarte Konfigurieren im Azure-Portal speichern. Siehe Bewährte Methoden zum Bereitstellen von Kennwörtern und anderen vertraulichen Daten für ASP.NET und Azure.

Geben Sie Ihre SendGrid-Anmeldeinformationen ein, führen Sie die App aus, registrieren Sie sich mit einem E-Mail-Alias, und wählen Sie den Bestätigungslink in Ihrer E-Mail aus. Wie Sie dies mit Ihrem Outlook.com-E-Mail-Konto tun können, erfahren Sie in John Attens C# SMTP-Konfiguration für Outlook.com SMTP Host und in seinerASP.NET Identity 2.0: Einrichten von Kontoprüfung und Zwei-Faktor-Autorisierung buchen.

Sobald ein Benutzer die Schaltfläche Registrieren auswählt, wird eine Bestätigungs-E-Mail mit einem Validierungstoken an seine E-Mail-Adresse gesendet.

Bild des E-Mail-Bestätigungsfensters

Der Benutzer wird eine E-Mail mit einem Bestätigungstoken für sein Konto gesendet.

Bild der empfangenen E-Mails

Code untersuchen

Der folgende Code veranschaulicht die POST ForgotPassword-Methode.

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);
}

Die Methode schlägt im Hintergrund fehl, wenn die Benutzer-E-Mail nicht bestätigt wurde. Wenn ein Fehler für eine ungültige E-Mail-Adresse gemeldet wurde, könnten schädliche Benutzer diese Information nutzen, um gültige Benutzeridentitäten (E-Mail-Aliase) für Angriffe zu finden.

Der folgende Code zeigt die ConfirmEmail Methode im Kontencontroller, die aufgerufen wird, wenn der Benutzer den Bestätigungslink in der an ihn gesendeten E-Mail auswählt.

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();
}

Nachdem ein vergessenes Kennworttoken verwendet wurde, wird es ungültig. Die folgende Codeänderung in der Create-Methode (in der Datei App_Start\IdentityConfig.cs) legt fest, dass die Token in 3 Stunden ablaufen.

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

Mit dem obigen Code laufen das vergessene Kennwort und die E-Mail-Bestätigungstoken in 3 Stunden ab. Der Standardwert TokenLifespan ist ein Tag.

Der folgende Code zeigt die E-Mail-Bestätigungsmethode:

// 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");
}

Um Ihre App sicherer zu machen, unterstützt ASP.NET Identity Two-Factor Authentifizierung (2FA). Siehe ASP.NET Identity 2.0: Einrichten von Kontoprüfung und Zwei-Faktor-Autorisierung von John Atten. Sie können zwar eine Kontosperre für fehlgeschlagene Versuche, sich mit einem Kennwort anzumelden, festlegen, aber dieser Ansatz macht Ihre Anmeldung anfällig für DOS-Sperren. Es wird empfohlen, die Kontosperrung nur mit 2FA zu verwenden.

Weitere Ressourcen