Partager via


Authentification à deux facteurs avec SMS dans ASP.NET Core

Par Rick Anderson et Swiss-Devs

Avertissement

Les applications d’authentificateur à deux facteurs (2FA) utilisant un algorithme de mot de passe à usage unique (TOTP) basé sur le temps sont l’approche recommandée par le secteur pour 2FA. L'utilisation de la 2FA avec le TOTP est préférable à celle de la 2FA par SMS. Pour plus d’informations, consultez Activer la génération de code QR pour les applications d’authentificateur TOTP dans ASP.NET Core pour ASP.NET Core 2.0 ou version ultérieure.

Ce tutoriel montre comment configurer l’authentification à deux facteurs (2FA) à l’aide de SMS. Des instructions sont fournies pour twilio et ASPSMS (https://www.aspsms.com/asp.net/identity/core/testcredits/), mais vous pouvez utiliser n’importe quel autre fournisseur SMS. Nous vous recommandons de terminer la confirmation de compte et la récupération de mot de passe avant de commencer ce didacticiel.

Affichez ou téléchargez l’exemple de code. Comment télécharger.

Créer un projet ASP.NET Core

Créez une application web ASP.NET Core nommée Web2FA avec des comptes individuels. Suivez les instructions de Enforce HTTPS dans ASP.NET Core pour configurer et imposer HTTPS.

Créer un compte SMS

Créez un compte SMS, par exemple, à partir de twilio ou ASPSMS (https://www.aspsms.com/asp.net/identity/core/testcredits/). Enregistrez les informations d’identification d’authentification (pour twilio : accountSid et authToken, pour ASPSMS : Userkey and Password).

Déterminer les informations d’identification du fournisseur SMS

Twilio :

Sous l’onglet Tableau de bord de votre compte Twilio, copiez le SID de compte et le jeton d’authentification.

ASPSMS :

Dans les paramètres de votre compte, accédez à Userkey et copiez-la avec votre mot de passe.

Nous allons ensuite stocker ces valeurs avec l’outil secret-manager dans les clés SMSAccountIdentification et SMSAccountPassword.

Spécification de SenderID / Originator

Twilio : Sous l’onglet Numéros, copiez votre numéro de téléphone Twilio.

ASPSMS : Dans le menu Déverrouiller les originateurs, déverrouillez un ou plusieurs originateurs ou choisissez un originateur alphanumérique (non pris en charge par tous les réseaux).

Nous allons ensuite stocker cette valeur avec l’outil secret-manager dans la clé SMSAccountFrom.

Fournir des informations d’identification pour le service SMS

Nous allons utiliser le modèle Options pour accéder au compte d’utilisateur et aux paramètres de clé.

  • Créez une classe pour récupérer la clé SMS sécurisée. Pour cet exemple, la SMSoptions classe est créée dans le Services/SMSoptions.cs fichier.
namespace Web2FA.Services
{
    public class SMSoptions
    {
        public string SMSAccountIdentification { get; set; }
        public string SMSAccountPassword { get; set; }
        public string SMSAccountFrom { get; set; }
    }
}

Définissez les SMSAccountIdentification, SMSAccountPassword et SMSAccountFrom avec l’outil secret-manager. Par exemple:

C:/Web2FA/src/WebApp1>dotnet user-secrets set SMSAccountIdentification 12345
info: Successfully saved SMSAccountIdentification = 12345 to the secret store.
  • Ajoutez le package NuGet pour le fournisseur SMS. À partir de la console du Gestionnaire de package (PMC), exécutez :

Twilio :

Install-Package Twilio

ASPSMS :

Install-Package ASPSMS

  • Ajoutez du code dans le Services/MessageServices.cs fichier pour activer SMS. Utilisez la section Twilio ou ASPSMS :

Twilio :

using Microsoft.Extensions.Options;
using System.Threading.Tasks;
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;

namespace Web2FA.Services
{
    // This class is used by the application to send Email and SMS
    // when you turn on two-factor authentication in ASP.NET Identity.
    // For more details see this link https://go.microsoft.com/fwlink/?LinkID=532713
    public class AuthMessageSender : IEmailSender, ISmsSender
    {
        public AuthMessageSender(IOptions<SMSoptions> optionsAccessor)
        {
            Options = optionsAccessor.Value;
        }

        public SMSoptions Options { get; }  // set only via Secret Manager

        public Task SendEmailAsync(string email, string subject, string message)
        {
            // Plug in your email service here to send an email.
            return Task.FromResult(0);
        }

        public Task SendSmsAsync(string number, string message)
        {
            // Plug in your SMS service here to send a text message.
            // Your Account SID from twilio.com/console
            var accountSid = Options.SMSAccountIdentification;
            // Your Auth Token from twilio.com/console
            var authToken = Options.SMSAccountPassword;

            TwilioClient.Init(accountSid, authToken);

            return MessageResource.CreateAsync(
              to: new PhoneNumber(number),
              from: new PhoneNumber(Options.SMSAccountFrom),
              body: message);
        }
    }
}

ASPSMS :

using Microsoft.Extensions.Options;
using System.Threading.Tasks;

namespace Web2FA.Services
{
    // This class is used by the application to send Email and SMS
    // when you turn on two-factor authentication in ASP.NET Identity.
    // For more details see this link https://go.microsoft.com/fwlink/?LinkID=532713
    public class AuthMessageSender : IEmailSender, ISmsSender
    {
        public AuthMessageSender(IOptions<SMSoptions> optionsAccessor)
        {
            Options = optionsAccessor.Value;
        }

        public SMSoptions Options { get; }  // set only via Secret Manager

        public Task SendEmailAsync(string email, string subject, string message)
        {
            // Plug in your email service here to send an email.
            return Task.FromResult(0);
        }

        public Task SendSmsAsync(string number, string message)
        {
            ASPSMS.SMS SMSSender = new ASPSMS.SMS();

            SMSSender.Userkey = Options.SMSAccountIdentification;
            SMSSender.Password = Options.SMSAccountPassword;
            SMSSender.Originator = Options.SMSAccountFrom;

            SMSSender.AddRecipient(number);
            SMSSender.MessageData = message;

            SMSSender.SendTextSMS();

            return Task.FromResult(0);
        }
    }
}

Configurer le démarrage à utiliser SMSoptions

Ajoutez SMSoptions au conteneur de service dans la méthode ConfigureServices dans Startup.cs :

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();
    services.Configure<SMSoptions>(Configuration);
}

Activer l’authentification à deux facteurs

Ouvrez le Views/Manage/Index.cshtmlRazor fichier d’affichage et supprimez les caractères de commentaire (donc aucun balisage n’est commenté).

Se connecter avec l’authentification à deux facteurs

  • Exécuter l’application et inscrire un nouvel utilisateur

Vue d'enregistrement de l'application web ouverte dans Microsoft Edge

  • Appuyez sur votre nom d’utilisateur, qui active la Index méthode d’action dans Manage controller. Appuyez ensuite sur le lien Ajouter un numéro de téléphone.

Gérer la vue - appuyez sur le lien « ajouter »

  • Ajoutez un numéro de téléphone qui recevra le code de vérification, puis appuyez sur Envoyer le code de vérification.

Page d'ajout de numéro de téléphone

  • Vous obtiendrez un sms avec le code de vérification. Entrez-le, puis appuyez sur Envoyer

Page de vérification du numéro de téléphone

Si vous n’obtenez pas de SMS, consultez la page du journal de logs Twilio.

  • La vue Gérer indique que votre numéro de téléphone a été ajouté avec succès.

Gérer la vue - numéro de téléphone ajouté avec succès

  • Appuyez sur Activer pour activer l’authentification à deux facteurs.

Gérer la vue - activer l’authentification à deux facteurs

Tester l’authentification à deux facteurs

  • Fermez la session.

  • Se connecter.

  • Le compte d’utilisateur a activé l’authentification à deux facteurs. Vous devez donc fournir le deuxième facteur d’authentification. Dans ce tutoriel, vous avez activé la vérification par téléphone. Les modèles intégrés vous permettent également de configurer l’e-mail comme deuxième facteur. Vous pouvez configurer des facteurs d'authentification supplémentaires, tels que les codes QR. Appuyez sur Envoyer.

Afficher le code de vérification

  • Entrez le code que vous obtenez dans le sms.

  • Si vous cliquez sur la case Mémoriser ce navigateur , vous n’avez pas besoin d’utiliser 2FA pour vous connecter lors de l’utilisation du même appareil et du même navigateur. L’activation de 2FA et le fait de cliquer sur Mémoriser ce navigateur vous fournira une protection forte 2FA contre les utilisateurs malveillants qui tentent d’accéder à votre compte, tant qu’ils n’ont pas accès à votre appareil. Vous pouvez le faire sur n’importe quel appareil privé que vous utilisez régulièrement. En définissant rappelez-vous ce navigateur, vous obtenez la sécurité ajoutée de 2FA à partir d’appareils que vous n’utilisez pas régulièrement, et vous bénéficiez de la commodité de ne pas avoir à passer par 2FA sur vos propres appareils.

Vérifier l’affichage

Verrouillage de compte pour la protection contre les attaques par force brute

Le verrouillage de compte est recommandé avec 2FA. Une fois qu’un utilisateur se connecte via un compte local ou un compte social, chaque tentative ayant échoué à 2FA est stockée. Si le nombre maximal de tentatives d’accès ayant échoué est atteint, l’utilisateur est verrouillé (par défaut : 5 minutes de verrouillage après 5 tentatives d’accès ayant échoué). Une authentification réussie réinitialise le nombre de tentatives d’accès ayant échoué et réinitialise l’horloge. La durée maximale des tentatives d’accès ayant échoué et du verrouillage peut être définie avec MaxFailedAccessAttempts et DefaultLockoutTimeSpan. Les éléments suivants configurent le verrouillage du compte pendant 10 minutes après 10 tentatives d’accès ayant échoué :

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddMvc();

    services.Configure<IdentityOptions>(options =>
    {
        options.Lockout.MaxFailedAccessAttempts = 10;
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10);
    });

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();
    services.Configure<SMSoptions>(Configuration);
}

Confirmez que PasswordSignInAsync définit lockoutOnFailure sur true :

var result = await _signInManager.PasswordSignInAsync(
                 Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true);