Confirmation de compte et récupération de mot deC#passe avec ASP.net Identity ()Account confirmation and password recovery with ASP.NET Identity (C#)

Avant de suivre ce didacticiel, vous devez d’abord créer une application web ASP.NET MVC 5 sécurisée avec connexion, confirmation par e-mail et réinitialisation du mot de passe.Before doing this tutorial you should first complete Create a secure ASP.NET MVC 5 web app with log in, email confirmation and password reset. Ce didacticiel contient plus de détails et vous indique comment configurer la messagerie électronique pour la confirmation du compte local et permettre aux utilisateurs de réinitialiser leur mot de passe oublié dans ASP.NET Identity.This tutorial contains more details and will show you how to set up email for local account confirmation and allow users to reset their forgotten password in ASP.NET Identity.

Un compte d’utilisateur local oblige l’utilisateur à créer un mot de passe pour le compte et ce mot de passe est stocké (en toute sécurité) dans l’application Web.A local user account requires the user to create a password for the account, and that password is stored (securely) in the web app. ASP.NET Identity prend également en charge les comptes sociaux, qui ne nécessitent pas que l’utilisateur crée un mot de passe pour l’application.ASP.NET Identity also supports social accounts, which don't require the user to create a password for the app. Les comptes sociaux utilisent un tiers (par exemple, Google, Twitter, Facebook ou Microsoft) pour authentifier les utilisateurs.Social accounts use a third party (such as Google, Twitter, Facebook, or Microsoft) to authenticate users. Cette rubrique couvre les sujets suivants :This topic covers the following:

Les nouveaux utilisateurs inscrivent leur alias de messagerie, ce qui crée un compte local.New users register their email alias, which creates a local account.

Le fait de sélectionner le bouton inscrire envoie un e-mail de confirmation contenant un jeton de validation à son adresse de messagerie.Selecting the Register button sends a confirmation email containing a validation token to their email address.

L’utilisateur reçoit un e-mail avec un jeton de confirmation pour son compte.The user is sent an email with a confirmation token for their account.

La sélection du lien confirme le compte.Selecting the link confirms the account.

Récupération/réinitialisation du mot de passePassword recovery/reset

Les utilisateurs locaux qui oublient leur mot de passe peuvent avoir un jeton de sécurité envoyé à leur compte de messagerie, ce qui leur permet de réinitialiser leur mot de passe.Local users who forget their password can have a security token sent to their email account, enabling them to reset their password.

L’utilisateur recevra bientôt un e-mail contenant un lien leur permettant de réinitialiser leur mot de passe.The user will soon get an email with a link allowing them to reset their password.


Si vous sélectionnez le lien, la page de réinitialisation est redéfinie.Selecting the link will take them to the Reset page.

Le fait de sélectionner le bouton Réinitialiser confirme que le mot de passe a été réinitialisé.Selecting the Reset button will confirm the password has been reset.

Créer une application web ASP.NETCreate an ASP.NET web app

Commencez par installer et exécuter Visual Studio 2017.Start by installing and running Visual Studio 2017.

  1. Créez un projet Web ASP.NET et sélectionnez le modèle MVC.Create a new ASP.NET Web project and select the MVC template. Web Forms également prendre en charge ASP.NET Identity, vous pouvez suivre des étapes similaires dans une application Web Forms.Web Forms also support ASP.NET Identity, so you could follow similar steps in a web forms app.

  2. Modifiez l’authentification en comptes d’utilisateur individuels.Change the authentication to Individual User Accounts.

  3. Exécutez l’application, sélectionnez le lien Register et inscrivez un utilisateur.Run the app, select the Register link and register a user. À ce stade, la seule validation sur l’e-mail est avec l’attribut [EmailAddress] .At this point, the only validation on the email is with the [EmailAddress] attribute.

  4. Dans Explorateur de serveurs, accédez à Data Connections\DefaultConnection\Tables\AspNetUsers, cliquez avec le bouton droit et sélectionnez ouvrir la définition de table.In Server Explorer, navigate to Data Connections\DefaultConnection\Tables\AspNetUsers, right-click and select Open table definition.

    L’illustration suivante montre le schéma de AspNetUsers :The following image shows the AspNetUsers schema:

  5. Cliquez avec le bouton droit sur la table AspNetUsers et sélectionnez afficher les donnéesde la table.Right-click on the AspNetUsers table and select Show Table Data.

    À ce stade, l’adresse de messagerie n’a pas été confirmée.At this point the email has not been confirmed.

Le magasin de données par défaut pour ASP.NET Identity est Entity Framework, mais vous pouvez le configurer pour utiliser d’autres magasins de données et ajouter des champs supplémentaires.The default data store for ASP.NET Identity is Entity Framework, but you can configure it to use other data stores and to add additional fields. Consultez la section ressources supplémentaires à la fin de ce didacticiel.See Additional Resources section at the end of this tutorial.

La classe de démarrage OWIN ( Startup.cs ) est appelée lorsque l’application démarre et appelle la méthode ConfigureAuth dans l' application_Start\Startup.auth.cs, qui configure le pipeline OWIN et initialise ASP.net Identity.The OWIN startup class ( Startup.cs ) is called when the app starts and invokes the ConfigureAuth method in App_Start\Startup.Auth.cs, which configures the OWIN pipeline and initializes ASP.NET Identity. Examinez la méthode ConfigureAuth.Examine the ConfigureAuth method. Chaque appel de CreatePerOwinContext inscrit un rappel (enregistré dans le OwinContext) qui sera appelé une fois par demande pour créer une instance du type spécifié.Each CreatePerOwinContext call registers a callback (saved in the OwinContext) that will be called once per request to create an instance of the specified type. Vous pouvez définir un point d’arrêt dans le constructeur et Create méthode de chaque type (ApplicationDbContext, ApplicationUserManager) et vérifier qu’ils sont appelés à chaque requête.You can set a break point in the constructor and Create method of each type (ApplicationDbContext, ApplicationUserManager) and verify they are called on each request. Une instance de ApplicationDbContext et ApplicationUserManager est stockée dans le contexte OWIN, accessible dans l’ensemble de l’application.A instance of ApplicationDbContext and ApplicationUserManager is stored in the OWIN context, which can be accessed throughout the application. ASP.NET Identity des hooks dans le pipeline OWIN via l’intergiciel de cookies.ASP.NET Identity hooks into the OWIN pipeline through cookie middleware. Pour plus d’informations, consultez Gestion de la durée de vie des demandes pour la classe usermanager dans ASP.net Identity.For more information, see Per request lifetime management for UserManager class in ASP.NET Identity.

Lorsque vous modifiez votre profil de sécurité, un nouveau tampon de sécurité est généré et stocké dans le champ SecurityStamp de la table AspNetUsers .When you change your security profile, a new security stamp is generated and stored in the SecurityStamp field of the AspNetUsers table. Notez que le champ SecurityStamp est différent du cookie de sécurité.Note, the SecurityStamp field is different from the security cookie. Le cookie de sécurité n’est pas stocké dans la table AspNetUsers (ou n’importe où ailleurs dans la base de l’identité).The security cookie is not stored in the AspNetUsers table (or anywhere else in the Identity DB). Le jeton de cookie de sécurité est auto-signé à l’aide de DPAPI et est créé avec les informations de UserId, SecurityStamp et d’heure d’expiration.The security cookie token is self-signed using DPAPI and is created with the UserId, SecurityStamp and expiration time information.

L’intergiciel de cookies vérifie le cookie à chaque requête.The cookie middleware checks the cookie on each request. La méthode SecurityStampValidator de la classe Startup atteint la base de donnée et vérifie périodiquement la présence d’un tampon de sécurité, comme spécifié avec le validateInterval.The SecurityStampValidator method in the Startup class hits the DB and checks security stamp periodically, as specified with the validateInterval. Cela se produit toutes les 30 minutes (dans notre exemple), sauf si vous modifiez votre profil de sécurité.This only happens every 30 minutes (in our sample) unless you change your security profile. L’intervalle de 30 minutes a été choisi pour limiter les allers-retours vers la base de données.The 30 minute interval was chosen to minimize trips to the database. Pour plus d’informations, consultez le didacticiel sur l’authentification à deux facteurs .See my two-factor authentication tutorial for more details.

En fonction des commentaires du code, la méthode UseCookieAuthentication prend en charge l’authentification par cookie.Per the comments in the code, the UseCookieAuthentication method supports cookie authentication. Le champ SecurityStamp et le code associé fournissent une couche supplémentaire de sécurité à votre application. quand vous modifiez votre mot de passe, vous êtes déconnecté du navigateur avec lequel vous vous êtes connecté.The SecurityStamp field and associated code provides an extra layer of security to your app, when you change your password, you will be logged out of the browser you logged in with. La méthode SecurityStampValidator.OnValidateIdentity permet à l’application de valider le jeton de sécurité lorsque l’utilisateur se connecte, ce qui est utilisé lorsque vous modifiez un mot de passe ou utilisez la connexion externe.The SecurityStampValidator.OnValidateIdentity method enables the app to validate the security token when the user logs in, which is used when you change a password or use the external login. Cela est nécessaire pour garantir que tous les jetons (cookies) générés avec l’ancien mot de passe sont invalidés.This is needed to ensure that any tokens (cookies) generated with the old password are invalidated. Dans l’exemple de projet, si vous modifiez le mot de passe des utilisateurs, un nouveau jeton est généré pour l’utilisateur, tous les jetons précédents sont invalidés et le champ SecurityStamp est mis à jour.In the sample project, if you change the users password then a new token is generated for the user, any previous tokens are invalidated and the SecurityStamp field is updated.

Le système d’identité vous permet de configurer votre application de sorte que le profil de sécurité des utilisateurs change (par exemple, lorsque l’utilisateur modifie son mot de passe ou modifie la connexion associée (par exemple, à partir de Facebook, Google, compte Microsoft, etc.), l’utilisateur se déconnecte de tous les instances de navigateur.The Identity system allow you to configure your app so when the users security profile changes (for example, when the user changes their password or changes associated login (such as from Facebook, Google, Microsoft account, etc.), the user is logged out of all browser instances. Par exemple, l’image ci-dessous montre l’exemple d’application SignOut unique , qui permet à l’utilisateur de se déconnecter de toutes les instances de navigateur (dans ce cas, IE, Firefox et chrome) en sélectionnant un bouton.For example, the image below shows the Single signout sample app, which allows the user to sign out of all browser instances (in this case, IE, Firefox and Chrome) by selecting one button. L’exemple vous permet également de vous déconnecter d’une instance de navigateur spécifique.Alternatively, the sample allows you to only log out of a specific browser instance.

L' exemple d’application SignOut unique montre comment ASP.net Identity vous permet de régénérer le jeton de sécurité.The Single signout sample app shows how ASP.NET Identity allows you to regenerate the security token. Cela est nécessaire pour garantir que tous les jetons (cookies) générés avec l’ancien mot de passe sont invalidés.This is needed to ensure that any tokens (cookies) generated with the old password are invalidated. Cette fonctionnalité fournit une couche supplémentaire de sécurité à votre application. Lorsque vous modifiez votre mot de passe, vous êtes déconnecté de l’emplacement où vous vous êtes connecté à cette application.This feature provides an extra layer of security to your application; when you change your password, you will be logged out where you have logged into this application.

Le fichier App_Start\IdentityConfig.cs contient les classes ApplicationUserManager, EmailService et SmsService.The App_Start\IdentityConfig.cs file contains the ApplicationUserManager, EmailService and SmsService classes. Les classes EmailService et SmsService implémentent chacune l’interface IIdentityMessageService. par conséquent, vous disposez de méthodes communes pour chaque classe afin de configurer la messagerie électronique et SMS.The EmailService and SmsService classes each implement the IIdentityMessageService interface, so you have common methods in each class to configure email and SMS. Bien que ce didacticiel montre uniquement comment ajouter des notifications par courrier électronique via SendGrid, vous pouvez envoyer des e-mails à l’aide de SMTP et d’autres mécanismes.Although this tutorial only shows how to add email notification through SendGrid, you can send email using SMTP and other mechanisms.

La classe Startup contient également une plaque de chaudière pour ajouter des connexions sociales (Facebook, Twitter, etc.). pour plus d’informations, consultez mon didacticiel application MVC 5 avec Facebook, Twitter, LinkedIn et l’authentification Google OAuth2 .The Startup class also contains boiler plate to add social logins (Facebook, Twitter, etc.), see my tutorial MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on for more info.

Examinez la classe ApplicationUserManager, qui contient les informations d’identité des utilisateurs et configure les fonctionnalités suivantes :Examine the ApplicationUserManager class, which contains the users identity information and configures the following features:

  • Exigences de la force du mot de passe.Password strength requirements.
  • Verrouillage de l’utilisateur (tentatives et temps).User lock out (attempts and time).
  • Authentification à deux facteurs (2FA).Two-factor authentication (2FA). Je vais aborder 2FA et SMS dans un autre didacticiel.I'll cover 2FA and SMS in another tutorial.
  • Raccordement de l’e-mail et des services SMS.Hooking up the email and SMS services. (Je couvrirai SMS dans un autre didacticiel).(I'll cover SMS in another tutorial).

La classe ApplicationUserManager dérive de la classe UserManager<ApplicationUser> générique.The ApplicationUserManager class derives from the generic UserManager<ApplicationUser> class. ApplicationUser dérive de IdentityUser.ApplicationUser derives from IdentityUser. IdentityUser dérive de la classe IdentityUser générique :IdentityUser derives from the generic IdentityUser class:

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

Les propriétés ci-dessus coïncident avec les propriétés de la table AspNetUsers, comme indiqué ci-dessus.The properties above coincide with the properties in the AspNetUsers table, shown above.

Les arguments génériques sur les IUser vous permettent de dériver une classe à l’aide de différents types pour la clé primaire.Generic arguments on IUser enable you to derive a class using different types for the primary key. Consultez l’exemple ChangePK qui montre comment modifier la clé primaire de String en int ou de GUID.See the ChangePK sample which shows how to change the primary key from string to int or GUID.

ApplicationUserApplicationUser

ApplicationUser (public class ApplicationUserManager : UserManager<ApplicationUser>) est défini dans Models\IdentityModels.cs comme suit :ApplicationUser (public class ApplicationUserManager : UserManager<ApplicationUser>) is defined in Models\IdentityModels.cs as:

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

Le code en surbrillance ci-dessus génère un ClaimsIdentity.The highlighted code above generates a ClaimsIdentity. ASP.NET Identity et l’authentification des cookies OWIN sont basées sur les revendications. par conséquent, l’infrastructure requiert que l’application génère un ClaimsIdentity pour l’utilisateur.ASP.NET Identity and OWIN Cookie Authentication are claims-based, therefore the framework requires the app to generate a ClaimsIdentity for the user. ClaimsIdentity contient des informations sur toutes les revendications pour l’utilisateur, telles que le nom de l’utilisateur, l’âge et les rôles auxquels l’utilisateur appartient.ClaimsIdentity has information about all the claims for the user, such as the user's name, age and what roles the user belongs to. Vous pouvez également ajouter d’autres revendications pour l’utilisateur à ce niveau.You can also add more claims for the user at this stage.

La méthode OWIN AuthenticationManager.SignIn transmet le ClaimsIdentity et se connecte à l’utilisateur :The OWIN AuthenticationManager.SignIn method passes in the ClaimsIdentity and signs in the user:

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

L' application MVC 5 avec Facebook, Twitter, LinkedIn et l’authentification Google OAuth2 montre comment vous pouvez ajouter des propriétés supplémentaires à la classe ApplicationUser.MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on shows how you can add additional properties to the ApplicationUser class.

Confirmation par e-mailEmail confirmation

Il est judicieux de confirmer l’adresse de messagerie à laquelle un nouvel utilisateur s’inscrit afin de vérifier qu’il n’emprunte pas l’identité d’un autre utilisateur (autrement dit, s’il ne s’est pas inscrit auprès de l’e-mail de quelqu’un d’autre).It's a good idea to confirm the email a new user register with to verify they are not impersonating someone else (that is, they haven't registered with someone else's email). Supposons que vous disposiez d’un forum de discussion, vous souhaitiez empêcher "bob@example.com" de vous inscrire en tant que "joe@contoso.com".Suppose you had a discussion forum, you would want to prevent "bob@example.com" from registering as "joe@contoso.com". Sans confirmation par courrier électronique, "joe@contoso.com" pouvez obtenir un courrier indésirable à partir de votre application.Without email confirmation, "joe@contoso.com" could get unwanted email from your app. Supposons que Bob s’est inscrit accidentellement comme "bib@example.com" et n’avait pas remarqué qu’il ne serait pas en mesure d’utiliser la récupération de mot de passe parce que l’application n’a pas son adresse e-mail correcte.Suppose Bob accidentally registered as "bib@example.com" and hadn't noticed it, he wouldn't be able to use password recover because the app doesn't have his correct email. La confirmation par courrier électronique fournit uniquement une protection limitée des robots et ne fournit pas de protection contre les spammeurs déterminés. ils ont de nombreux alias de messagerie de travail qu’ils peuvent utiliser pour s’inscrire. Dans l’exemple ci-dessous, l’utilisateur ne peut pas modifier son mot de passe tant que son compte n’a pas été confirmé (en sélectionnant un lien de confirmation reçu sur le compte de messagerie qu’il a inscrit avec). Vous pouvez appliquer ce processus à d’autres scénarios, par exemple en envoyant un lien pour confirmer et réinitialiser le mot de passe sur les nouveaux comptes créés par l’administrateur, en envoyant un e-mail à l’utilisateur lorsqu’il a modifié son profil, et ainsi de suite.Email confirmation provides only limited protection from bots and doesn't provide protection from determined spammers, they have many working email aliases they can use to register.In the sample below, the user won't be able to change their password until their account has been confirmed (by them selecting a confirmation link received on the email account they registered with.) You can apply this work flow to other scenarios, for example sending a link to confirm and reset the password on new accounts created by the administrator, sending the user an email when they have changed their profile and so on. En règle générale, vous souhaitez empêcher les nouveaux utilisateurs d'envoyer des données à votre site web avant qu’ils soient confirmés par courrier électronique, par SMS ou via un autre mécanisme.You generally want to prevent new users from posting any data to your web site before they have been confirmed by email, a SMS text message or another mechanism.

Créer un exemple plus completBuild a more complete sample

Dans cette section, vous allez utiliser NuGet pour télécharger un exemple plus complet avec lequel nous allons travailler.In this section, you'll use NuGet to download a more complete sample we will work with.

  1. Créez un projet Web ASP.NET vide .Create a new empty ASP.NET Web project.

  2. Dans la console du gestionnaire de package, entrez les commandes suivantes :In the Package Manager Console, enter the following commands:

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

    Dans ce didacticiel, nous allons utiliser SendGrid pour envoyer des courriers électroniques.In this tutorial, we'll use SendGrid to send email. Le package Identity.Samples installe le code que nous allons utiliser.The Identity.Samples package installs the code we will be working with.

  3. Définissez le projet pour utiliser SSL.Set the project to use SSL.

  4. Testez la création du compte local en exécutant l’application, en sélectionnant le lien Register et en publiant le formulaire d’inscription.Test local account creation by running the app, selecting the Register link, and posting the registration form.

  5. Sélectionnez le lien e-mail de démonstration, qui simule la confirmation de l’e-mail.Select the demo email link, which simulates email confirmation.

  6. Supprimez le code de confirmation de la liaison par e-mail de démonstration de l’exemple (le code ViewBag.Link dans le contrôleur de compte.Remove the demo email link confirmation code from the sample (The ViewBag.Link code in the account controller. Consultez les méthodes d’action DisplayEmail et ForgotPasswordConfirmation et les vues Razor).See the DisplayEmail and ForgotPasswordConfirmation action methods and razor views ).

Warning

Si vous modifiez l’un des paramètres de sécurité de cet exemple, les applications de production doivent subir un audit de sécurité qui appelle explicitement les modifications apportées.If you change any of the security settings in this sample, productions apps will need to undergo a security audit that explicitly calls the changes made.

Examinez le code dans l’application_Start\IdentityConfig.csExamine the code in App_Start\IdentityConfig.cs

L’exemple montre comment créer un compte et l’ajouter au rôle d' administrateur .The sample shows how to create an account and add it to the Admin role. Vous devez remplacer l’adresse de messagerie dans l’exemple par le courrier électronique que vous allez utiliser pour le compte d’administrateur.You should replace the email in the sample with the email you will be using for the admin account. La méthode la plus simple pour créer un compte d’administrateur est par programmation dans la méthode Seed.The easiest way right now to create an administrator account is programmatically in the Seed method. Nous espérons avoir un outil à l’avenir qui vous permettra de créer et d’administrer des utilisateurs et des rôles.We hope to have a tool in the future that will allow you to create and administer users and roles. L’exemple de code vous permet de créer et de gérer des utilisateurs et des rôles, mais vous devez d’abord disposer d’un compte administrateurs pour exécuter les pages rôles et administrateur d’utilisateur.The sample code does let you create and manage users and roles, but you must first have an administrators account to run the roles and user admin pages. Dans cet exemple, le compte d’administrateur est créé lorsque la base de code est amorcée.In this sample, the admin account is created when the DB is seeded.

Modifiez le mot de passe et remplacez le nom par un compte dans lequel vous pouvez recevoir des notifications par courrier électronique.Change the password and change the name to an account where you can receive email notifications.

Warning

Sécurité - Ne jamais stocker de données sensibles dans votre code source.Security - Never store sensitive data in your source code.

Comme mentionné précédemment, l’appel de app.CreatePerOwinContext dans la classe Startup ajoute des rappels à la méthode Create du contenu de la base de données de l’application, au gestionnaire des utilisateurs et aux classes de gestionnaires de rôles.As mentioned previously, the app.CreatePerOwinContext call in the startup class adds callbacks to the Create method of the app DB content, user manager and role manger classes. Le pipeline OWIN appelle la méthode Create sur ces classes pour chaque requête et stocke le contexte pour chaque classe.The OWIN pipeline calls the Create method on these classes for each request and stores the context for each class. Le contrôleur de compte expose le gestionnaire des utilisateurs à partir du contexte HTTP (qui contient le contexte OWIN) :The account controller exposes the user manager from the HTTP context (which contains the OWIN context):

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

Lorsqu’un utilisateur inscrit un compte local, la méthode HTTP Post Register est appelée :When a user registers a local account, the HTTP Post Register method is called:

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

Le code ci-dessus utilise les données du modèle pour créer un nouveau compte d’utilisateur à l’aide de l’adresse de messagerie et du mot de passe entrés.The code above uses the model data to create a new user account using the email and password entered. Si l’alias de messagerie se trouve dans le magasin de données, la création du compte échoue et le formulaire s’affiche à nouveau.If the email alias is in the data store, account creation fails and the form is displayed again. La méthode GenerateEmailConfirmationTokenAsync crée un jeton de confirmation sécurisé et le stocke dans le magasin de données ASP.NET Identity.The GenerateEmailConfirmationTokenAsync method creates a secure confirmation token and stores it in the ASP.NET Identity data store. La méthode URL. action crée un lien contenant le UserId et le jeton de confirmation.The Url.Action method creates a link containing the UserId and confirmation token. Ce lien est ensuite envoyé par courrier électronique à l’utilisateur, l’utilisateur peut sélectionner le lien dans son application de messagerie pour confirmer son compte.This link is then emailed to the user, the user can select on the link in their email app to confirm their account.

Configurer la confirmation par e-mailSet up email confirmation

Accédez à la page d’inscription à Azure SendGrid et inscrivez-vous pour obtenir un compte gratuit.Go to the Azure SendGrid sign up page and register for free account. Ajoutez du code semblable au suivant pour configurer SendGrid :Add code similar to the following to configure 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);
      }
   }
}

Note

Les clients de messagerie acceptent souvent uniquement les messages texte (pas de code HTML).Email clients frequently accept only text messages (no HTML). Vous devez fournir le message au format texte et HTML.You should provide the message in text and HTML. Dans l’exemple SendGrid ci-dessus, cette opération est effectuée avec le myMessage.Text et myMessage.Html code indiqué ci-dessus.In the SendGrid sample above, this is done with the myMessage.Text and myMessage.Html code shown above.

Le code suivant montre comment envoyer un e-mail à l’aide de la classe MailMessagemessage.Body retourne uniquement le lien.The following code shows how to send email using the MailMessage class where message.Body returns only the 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);
}

Warning

Sécurité - Ne jamais stocker de données sensibles dans votre code source.Security - Never store sensitive data in your source code. Le compte et les informations d’identification sont stockés dans l’appSetting.The account and credentials are stored in the appSetting. Sur Azure, vous pouvez stocker ces valeurs en toute sécurité sous l’onglet configurer de la portail Azure.On Azure, you can securely store these values on the Configure tab in the Azure portal. Consultez meilleures pratiques pour le déploiement de mots de passe et d’autres données sensibles dans ASP.net et Azure.See Best practices for deploying passwords and other sensitive data to ASP.NET and Azure.

Entrez vos informations d’identification SendGrid, exécutez l’application, inscrivez-vous avec un alias de messagerie vous pouvez sélectionner le lien confirmer dans votre e-mail.Enter your SendGrid credentials, run the app, register with an email alias can select the confirm link in your email. Pour savoir comment faire avec votre compte de messagerie Outlook.com , consultez Configuration SMTP de John atten C# pour l’hôte SMTP Outlook.com et sonASP.net Identity 2,0 : configuration de la validation de compte et des publications d’autorisation à deux facteurs .To see how to do this with your Outlook.com email account, see John Atten's C# SMTP Configuration for Outlook.Com SMTP Host and hisASP.NET Identity 2.0: Setting Up Account Validation and Two-Factor Authorization posts.

Une fois qu’un utilisateur a sélectionné le bouton inscrire , un e-mail de confirmation contenant un jeton de validation est envoyé à son adresse de messagerie.Once a user selects the Register button a confirmation email containing a validation token is sent to their email address.

L’utilisateur reçoit un e-mail avec un jeton de confirmation pour son compte.The user is sent an email with a confirmation token for their account.

Examiner le codeExamine the code

Le code suivant montre la méthode POST ForgotPassword.The following code shows the POST ForgotPassword method.

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

La méthode échoue en silence si la messagerie de l’utilisateur n’a pas été confirmée.The method fails silently if the user email has not been confirmed. Si une erreur a été publiée pour une adresse de messagerie non valide, des utilisateurs malveillants pouvaient utiliser ces informations pour trouver des ID d’utilisateur (alias de messagerie) valides pour attaquer.If an error was posted for an invalid email address, malicious users could use that information to find valid userId (email aliases) to attack.

Le code suivant montre la méthode ConfirmEmail dans le contrôleur de compte qui est appelée lorsque l’utilisateur sélectionne le lien de confirmation dans le message électronique qui lui est envoyé :The following code shows the ConfirmEmail method in the account controller that is called when the user selects the confirmation link in the email sent to them:

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

Une fois qu’un jeton de mot de passe oublié a été utilisé, il est invalidé.Once a forgotten password token has been used, it's invalidated. La modification de code suivante dans la méthode Create (dans le fichier App_Start\IdentityConfig.cs ) définit les jetons pour qu’ils expirent dans 3 heures.The following code change in the Create method (in the App_Start\IdentityConfig.cs file) sets the tokens to expire in 3 hours.

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

Avec le code ci-dessus, le mot de passe oublié et les jetons de confirmation par courrier électronique expirent dans 3 heures.With the code above, the forgotten password and the email confirmation tokens will expire in 3 hours. La TokenLifespan par défaut est d’un jour.The default TokenLifespan is one day.

Le code suivant illustre la méthode de confirmation par courrier électronique :The following code shows the email confirmation method:

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

Pour renforcer la sécurité de votre application, ASP.NET Identity prend en charge l’authentification à deux facteurs (2FA).To make your app more secure, ASP.NET Identity supports Two-Factor authentication (2FA). Consultez ASP.NET Identity 2,0 : configuration de la validation de compte et de l’autorisation à deux facteurs par John atten.See ASP.NET Identity 2.0: Setting Up Account Validation and Two-Factor Authorization by John Atten. Bien que vous puissiez définir le verrouillage de compte lors de tentatives de mot de passe de connexion, cette approche rend votre connexion vulnérable aux verrouillages dos .Although you can set account lockout on login password attempt failures, that approach makes your login susceptible to DOS lockouts. Nous vous recommandons d’utiliser le verrouillage de compte uniquement avec 2FA.We recommend you use account lockout only with 2FA.

Ressources supplémentairesAdditional resources