Autenticazione a due fattori con SMS in ASP.NET Core

Di Rick Anderson e Swiss-Devs

Avviso

Le app di autenticazione a due fattori (2FA), che usano un algoritmo TOTP (One-Time Password Algorithm), sono l'approccio consigliato dal settore per 2FA. 2FA con TOTP è preferibile a SMS 2FA. Per altre informazioni, vedere Abilitare la generazione di codice a matrice per le app di autenticazione TOTP in ASP.NET Core per ASP.NET Core 2.0 e versioni successive.

Questa esercitazione illustra come configurare l'autenticazione a due fattori (2FA) tramite SMS. Le istruzioni vengono fornite per twilio e ASPSMS, ma è possibile usare qualsiasi altro provider SMS. Prima di iniziare questa esercitazione, è consigliabile completare la conferma dell'account e il ripristino delle password.

Visualizzare o scaricare il codice di esempio. Come scaricare.

Creare un nuovo progetto ASP.NET Core

Creare una nuova app Web ASP.NET Core denominata Web2FA con singoli account utente. Seguire le istruzioni in Applicare HTTPS in ASP.NET Core per configurare e richiedere HTTPS.

Creare un account SMS

Creare un account SMS, ad esempio, da twilio o ASPSMS. Registrare le credenziali di autenticazione (per twilio: accountSid e authToken, per ASPSMS: Userkey e Password).

Comprendere le credenziali del provider SMS

Twilio:

Nella scheda Dashboard dell'account Twilio copiare il SID account e il token di autenticazione.

ASPSMS:

Dalle impostazioni dell'account passare a Userkey e copiarlo insieme alla password.

Questi valori verranno archiviati in un secondo momento con lo strumento secret-manager all'interno delle chiavi SMSAccountIdentification e SMSAccountPassword.

Specifica di SenderID/Originator

Twilio: nella scheda Numeri copiare il numero di telefono twilio.

ASPSMS: nel menu Sblocca originatori sbloccare uno o più originatori o scegliere un originatore alfanumerico (non supportato da tutte le reti).

Questo valore verrà archiviato successivamente con lo strumento secret-manager all'interno della chiave SMSAccountFrom.

Specificare le credenziali per il servizio SMS

Verrà usato il modello Opzioni per accedere alle impostazioni dell'account utente e della chiave.

  • Creare una classe per recuperare la chiave SMS sicura. Per questo esempio, la SMSoptions classe viene creata nel Services/SMSoptions.cs file .
namespace Web2FA.Services
{
    public class SMSoptions
    {
        public string SMSAccountIdentification { get; set; }
        public string SMSAccountPassword { get; set; }
        public string SMSAccountFrom { get; set; }
    }
}

SMSAccountIdentificationImpostare e SMSAccountPassword SMSAccountFrom con lo strumento secret-manager. Ad esempio:

C:/Web2FA/src/WebApp1>dotnet user-secrets set SMSAccountIdentification 12345
info: Successfully saved SMSAccountIdentification = 12345 to the secret store.
  • Aggiungere il pacchetto NuGet per il provider SMS. Dalla console Gestione pacchetti (PMC) eseguire:

Twilio:

Install-Package Twilio

ASPSMS:

Install-Package ASPSMS

  • Aggiungere il Services/MessageServices.cs codice nel file per abilitare SMS. Usare la sezione Twilio o 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);
        }
    }
}

Configurare l'avvio da usare SMSoptions

Aggiungere SMSoptions al contenitore del servizio nel ConfigureServices metodo in Startup.cs:

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

Abilita l'autenticazione a due fattori

Aprire il file di Views/Manage/Index.cshtmlRazor visualizzazione e rimuovere i caratteri di commento ( in modo che nessun markup venga impostato come commento).

Accedere con l'autenticazione a due fattori

  • Eseguire l'app e registrare un nuovo utente

Web application Register view open in Microsoft Edge

  • Toccare il nome utente, che attiva il Index metodo di azione in Gestisci controller. Toccare quindi il numero di telefono Aggiungi collegamento.

Manage view - tap the

  • Aggiungere un numero di telefono che riceverà il codice di verifica e toccare Invia codice di verifica.

Add Phone Number page

  • Verrà visualizzato un sms con il codice di verifica. Immetterlo e toccare Invia

Verify Phone Number page

Se non viene visualizzato un sms, vedere la pagina di log twilio.

  • La visualizzazione Gestisci mostra che il numero di telefono è stato aggiunto correttamente.

Manage view - phone number added successfully

  • Toccare Abilita per abilitare l'autenticazione a due fattori.

Manage view - enable two-factor authentication

Testare l'autenticazione a due fattori

  • Disconnettersi.

  • Eseguire l'accesso.

  • L'account utente ha abilitato l'autenticazione a due fattori, quindi è necessario fornire il secondo fattore di autenticazione. In questa esercitazione è stata abilitata la verifica tramite telefono. I modelli predefiniti consentono anche di configurare la posta elettronica come secondo fattore. È possibile configurare altri secondi fattori per l'autenticazione, ad esempio codici a matrice. Toccare Invia.

Send Verification Code view

  • Immettere il codice visualizzato nel messaggio SMS.

  • Facendo clic sulla casella di controllo Memorizza questo browser , è possibile esentare dall'uso di 2FA per l'accesso quando si usa lo stesso dispositivo e lo stesso browser. L'abilitazione di 2FA e il clic su Memorizza questo browser fornirà una protezione 2FA avanzata da utenti malintenzionati che tentano di accedere all'account, purché non abbiano accesso al dispositivo. È possibile eseguire questa operazione su qualsiasi dispositivo privato usato regolarmente. Impostando Ricorda questo browser, si ottiene la sicurezza aggiuntiva di 2FA dai dispositivi che non si usano regolarmente e si ottiene la comodità di non dover passare attraverso 2FA sui propri dispositivi.

Verify view

Blocco dell'account per la protezione da attacchi di forza bruta

Il blocco dell'account è consigliato con 2FA. Una volta che un utente accede tramite un account locale o un account di social networking, ogni tentativo non riuscito a 2FA viene archiviato. Se viene raggiunto il numero massimo di tentativi di accesso non riusciti, l'utente viene bloccato (impostazione predefinita: blocco di 5 minuti dopo 5 tentativi di accesso non riusciti). Un'autenticazione riuscita reimposta il conteggio dei tentativi di accesso non riusciti e reimposta l'orologio. Il numero massimo di tentativi di accesso non riusciti e il tempo di blocco possono essere impostati con MaxFailedAccessAttempts e DefaultLockoutTimeSpan. Di seguito viene configurato il blocco dell'account per 10 minuti dopo 10 tentativi di accesso non riusciti:

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

Confermare che PasswordSignInAsync imposta su lockoutOnFailure true:

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