Uwierzytelnianie dwuskładnikowe z wiadomością SMS w programie ASP.NET Core

Autor : Rick Anderson i Swiss-Devs

Ostrzeżenie

Aplikacje uwierzytelniające uwierzytelniania dwuskładnikowego (2FA, Time-based One-Time Password Algorithm, TOTP) to zalecane w branży podejście do uwierzytelniania 2FA. Uwierzytelnianie 2FA przy użyciu protokołu TOTP jest preferowane do uwierzytelniania SMS 2FA. Aby uzyskać więcej informacji, zobacz Enable QR Code generation for TOTP authenticator apps in ASP.NET Core for ASP.NET Core 2.0 and later (Włączanie generowania kodu QR dla aplikacji uwierzytelniania TOTP w programie ASP.NET Core dla platformy ASP.NET Core 2.0 lub nowszej).

W tym samouczku pokazano, jak skonfigurować uwierzytelnianie dwuskładnikowe (2FA) przy użyciu programu SMS. Instrukcje są podane dla usług twilio i ASPSMS, ale można użyć dowolnego innego dostawcy programu SMS. Przed rozpoczęciem tego samouczka zalecamy ukończenie potwierdzania konta i odzyskiwania hasła.

Wyświetl lub pobierz kod przykładowy. Jak pobrać.

Tworzenie nowego projektu ASP.NET Core

Utwórz nową aplikację internetową platformy ASP.NET Core o nazwie z Web2FA indywidualnymi kontami użytkowników. Postępuj zgodnie z instrukcjami w temacie Wymuszanie protokołu HTTPS w programie ASP.NET Core , aby skonfigurować i wymagać protokołu HTTPS.

Tworzenie konta SMS

Utwórz konto SMS, na przykład z usługi twilio lub ASPSMS. Rejestruj poświadczenia uwierzytelniania (dla usługi twilio: accountSid i authToken, dla usługi ASPSMS: Userkey i Password).

Określanie poświadczeń dostawcy programu SMS

Twilio:

Na karcie Pulpit nawigacyjny konta usługi Twilio skopiuj identyfikator SID konta i token uwierzytelniania.

ASPSMS:

W ustawieniach konta przejdź do pozycji Userkey i skopiuj je razem z hasłem.

Później zapiszemy te wartości za pomocą narzędzia secret-manager w ramach kluczy SMSAccountIdentification i SMSAccountPassword.

Określanie identyfikatora nadawcy/inicjatora

Twilio: na karcie Numery skopiuj swój numer telefonu Twilio.

ASPSMS: W menu Odblokuj elementy źródłowe odblokuj co najmniej jeden obiekt źródłowy lub wybierz alfanumeryczną jednostki źródłowej (nieobsługiwane przez wszystkie sieci).

Później zapiszemy tę wartość za pomocą narzędzia secret-manager w kluczu SMSAccountFrom.

Podaj poświadczenia dla usługi SMS

Użyjemy wzorca Opcje, aby uzyskać dostęp do konta użytkownika i ustawień klucza.

  • Utwórz klasę, aby pobrać bezpieczny klucz SMS. W tym przykładzie SMSoptions klasa jest tworzona Services/SMSoptions.cs w pliku .
namespace Web2FA.Services
{
    public class SMSoptions
    {
        public string SMSAccountIdentification { get; set; }
        public string SMSAccountPassword { get; set; }
        public string SMSAccountFrom { get; set; }
    }
}

Ustaw element SMSAccountIdentificationSMSAccountPassword i SMSAccountFrom za pomocą narzędzia secret-manager. Przykład:

C:/Web2FA/src/WebApp1>dotnet user-secrets set SMSAccountIdentification 12345
info: Successfully saved SMSAccountIdentification = 12345 to the secret store.
  • Dodaj pakiet NuGet dla dostawcy programu SMS. Z poziomu konsoli Menedżer pakietów (PMC) uruchom polecenie:

Twilio:

Install-Package Twilio

ASPSMS:

Install-Package ASPSMS

  • Dodaj kod w pliku, Services/MessageServices.cs aby włączyć program SMS. Użyj sekcji Twilio lub 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);
        }
    }
}

Konfigurowanie uruchamiania do użycia SMSoptions

Dodaj SMSoptions do kontenera usługi w metodzie ConfigureServices w pliku Startup.cs:

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

Włącz uwierzytelnianie dwuskładnikowe

Views/Manage/Index.cshtmlRazor Otwórz plik widoku i usuń znaki komentarza (więc żaden znacznik nie jest komentowany).

Logowanie przy użyciu uwierzytelniania dwuskładnikowego

  • Uruchamianie aplikacji i rejestrowanie nowego użytkownika

Web application Register view open in Microsoft Edge

  • Naciśnij nazwę użytkownika, która aktywuje metodę Index akcji w obszarze Zarządzanie kontrolerem. Następnie naciśnij numer telefonu Dodaj link.

Manage view - tap the

  • Dodaj numer telefonu, który otrzyma kod weryfikacyjny, i naciśnij pozycję Wyślij kod weryfikacyjny.

Add Phone Number page

  • Otrzymasz wiadomość SMS z kodem weryfikacyjnym. Wprowadź go i naciśnij pozycję Prześlij

Verify Phone Number page

Jeśli nie otrzymasz wiadomości SMS, zobacz stronę dziennika usługi twilio.

  • Widok Zarządzaj pokazuje, że numer telefonu został dodany pomyślnie.

Manage view - phone number added successfully

  • Naciśnij pozycję Włącz , aby włączyć uwierzytelnianie dwuskładnikowe.

Manage view - enable two-factor authentication

Testowanie uwierzytelniania dwuskładnikowego

  • Wyloguj się.

  • Zaloguj się.

  • Konto użytkownika włączyło uwierzytelnianie dwuskładnikowe, więc musisz podać drugi czynnik uwierzytelniania. W tym samouczku włączono weryfikację telefonu. Wbudowane szablony umożliwiają również skonfigurowanie poczty e-mail jako drugiego czynnika. Możesz skonfigurować dodatkowe dodatkowe czynniki drugie na potrzeby uwierzytelniania, takiego jak kody QR. Naciśnij pozycję Prześlij.

Send Verification Code view

  • Wprowadź kod otrzymany w wiadomości SMS.

  • Kliknięcie pola wyboru Zapamiętaj tę przeglądarkę spowoduje wykluczenie konieczności korzystania z uwierzytelniania 2FA w celu zalogowania się podczas korzystania z tego samego urządzenia i przeglądarki. Włączenie uwierzytelniania 2FA i kliknięcie pozycji Zapamiętaj tę przeglądarkę zapewni silną ochronę 2FA przed złośliwymi użytkownikami próbującymi uzyskać dostęp do konta, o ile nie mają dostępu do urządzenia. Można to zrobić na dowolnym urządzeniu prywatnym, którego regularnie używasz. Ustawiając ustawienie Zapamiętaj tę przeglądarkę, uzyskujesz dodatkowe zabezpieczenia uwierzytelniania 2FA z urządzeń, których nie używasz regularnie, i możesz uzyskać wygodę, aby nie trzeba było przechodzić przez uwierzytelnianie 2FA na własnych urządzeniach.

Verify view

Blokada konta w celu ochrony przed atakami siłowymi

Blokada konta jest zalecana w przypadku uwierzytelniania 2FA. Gdy użytkownik zaloguje się za pośrednictwem konta lokalnego lub konta społecznościowego, każda nieudana próba 2FA jest przechowywana. Jeśli zostanie osiągnięta maksymalna liczba nieudanych prób dostępu, użytkownik zostanie zablokowany (domyślnie: 5 minut blokady po 5 nieudanych próbach dostępu). Pomyślne uwierzytelnienie resetuje liczbę nieudanych prób dostępu i resetuje zegar. Maksymalna liczba nieudanych prób dostępu i czas blokady można ustawić za pomocą MaxFailedAccessAttempts poleceń i DefaultLockoutTimeSpan. Poniżej skonfigurowano blokadę konta przez 10 minut po 10 nieudanych próbach dostępu:

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

Upewnij się, że PasswordSignInAsync ustawiono wartość lockoutOnFailuretrue:

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