Поделиться через


Двухфакторная проверка подлинности с помощью SMS в ASP.NET Core

Рик Андерсон и швейцарские разработчики

Warning

Два приложения проверки подлинности (2FA) с использованием однократного алгоритма пароля на основе времени (TOTP) — это рекомендуемый в отрасли подход для 2FA. 2FA, использующий TOTP, предпочтителен для SMS 2FA. Дополнительные сведения см. в разделе "Включение создания QR-кода для приложений проверки подлинности TOTP в ASP.NET Core" для ASP.NET Core 2.0 или более поздней версии.

В этом руководстве показано, как настроить двухфакторную проверку подлинности (2FA) с помощью SMS. Инструкции приведены для twilio и ASPSMS (https://www.aspsms.com/asp.net/identity/core/testcredits/), но вы можете использовать любой другой поставщик SMS. Перед началом работы с этим руководством рекомендуется завершить подтверждение учетной записи и восстановление паролей .

Просмотреть или скачать образец кода. Скачивание.

Создание нового проекта ASP.NET Core

Создайте новое веб-приложение ASP.NET Core Web2FA с отдельными учетными записями. Следуйте инструкциям в разделе "Принудительное применение HTTPS" в ASP.NET Core , чтобы настроить и требовать HTTPS.

Создание учетной записи SMS

Создайте учетную запись SMS, например из twilio или ASPSMS (https://www.aspsms.com/asp.net/identity/core/testcredits/). Запишите учетные данные проверки подлинности (для Twilio: accountSid и authToken, для ASPSMS: Userkey и Password).

Определение учетных данных поставщика SMS

Twilio:

На вкладке "Панель мониторинга" учетной записи Twilio скопируйте идентификатор безопасности учетной записи и маркер проверки подлинности.

ASPSMS:

В параметрах учетной записи перейдите в Userkey и скопируйте его вместе с паролем.

Позже мы будем хранить эти значения с помощью средства secret-manager в ключах SMSAccountIdentification и SMSAccountPassword.

Указание отправителя / инициатора

Twilio: На вкладке "Номера" скопируйте номер телефона Twilio.

ASPSMS: В меню "Разблокировка источников" разблокируйте один или несколько источников или выберите буквенно-цифровой источник (не поддерживается всеми сетями).

Позже мы будем хранить это значение с помощью средства secret-manager в ключе SMSAccountFrom.

Укажите учетные данные для службы SMS

Мы будем использовать шаблон параметров для доступа к учетной записи пользователя и ключевым параметрам.

  • Создайте класс, чтобы получить безопасный SMS-ключ. В этом примере SMSoptions класс создается в Services/SMSoptions.cs файле.
namespace Web2FA.Services
{
    public class SMSoptions
    {
        public string SMSAccountIdentification { get; set; }
        public string SMSAccountPassword { get; set; }
        public string SMSAccountFrom { get; set; }
    }
}

Задайте значения SMSAccountIdentification, SMSAccountPassword и SMSAccountFrom с помощью средства secret-manager. Рассмотрим пример.

C:/Web2FA/src/WebApp1>dotnet user-secrets set SMSAccountIdentification 12345
info: Successfully saved SMSAccountIdentification = 12345 to the secret store.
  • Добавьте пакет NuGet для поставщика SMS. Из консоли диспетчера пакетов (PMC) выполните следующую команду:

Twilio:

Install-Package Twilio

ASPSMS:

Install-Package ASPSMS

  • Добавьте код в Services/MessageServices.cs файл, чтобы включить SMS. Используйте Twilio или раздел 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);
        }
    }
}

Настройка запуска для использования SMSoptions

Добавьте SMSoptions в контейнер службы в методе ConfigureServices: Startup.cs

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

Включение двухфакторной проверки подлинности

Views/Manage/Index.cshtml Razor Откройте файл представления и удалите символы комментариев (поэтому разметка не закомментирована).

Вход с помощью двухфакторной проверки подлинности

  • Запустите приложение и зарегистрируйте нового пользователя

Страница регистрации веб-приложения открывается в Microsoft Edge

  • Коснитесь имени пользователя, чтобы активировать метод Index в контроллере Manage. Затем коснитесь ссылки Добавить, относящейся к номеру телефона.

Управление представлением— коснитесь ссылки

  • Добавьте номер телефона, который получит код проверки и нажмите кнопку "Отправить код проверки".

Страница

  • Вы получите текстовое сообщение с кодом проверки. Введите его и нажмите кнопку "Отправить"

Страница

Если вы не получаете текстовое сообщение, посмотрите страницу с журналами Twilio.

  • В вкладке "Управление" отображается, что номер вашего телефона был успешно добавлен.

Управление представлением — номер телефона успешно добавлен

  • Нажмите кнопку "Включить ", чтобы включить двухфакторную проверку подлинности.

Управление представлением — включение двухфакторной проверки подлинности

Проверка двухфакторной проверки подлинности

  • Выйдите из системы.

  • Войти.

  • Учетная запись пользователя включила двухфакторную проверку подлинности, поэтому необходимо предоставить второй фактор проверки подлинности. В этом руководстве вы включили проверку телефона. Встроенные шаблоны также позволяют настроить электронную почту в качестве второго фактора. Можно настроить дополнительные дополнительные факторы проверки подлинности, такие как QR-коды. Нажмите кнопку "Отправить".

Отправка представления кода проверки

  • Введите код, который вы получаете в SMS-сообщении.

  • Установите флажок "Запомнить этот браузер ", чтобы исключить необходимость использования 2FA для входа при использовании того же устройства и браузера. Включение 2FA и нажатие кнопки "Запомнить этот браузер " обеспечит надежную защиту 2FA от злоумышленников, пытающихся получить доступ к вашей учетной записи, если у них нет доступа к устройству. Это можно сделать на любом частном устройстве, которое вы регулярно используете. Включив функцию Запомнить этот браузер, вы получаете дополнительную безопасность через 2FA с устройств, которые вы используете не регулярно, а также удобство, избегая прохождения 2FA на собственных устройствах.

Проверка представления

Блокировка учетной записи для защиты от атак методом перебора

Рекомендуется использовать блокировку учетной записи с двухфакторной аутентификацией. После входа пользователя с помощью локальной учетной записи или учетной записи социальной сети каждая неудачная попытка 2FA сохраняется. Если достигнуто максимальное количество неудачных попыток доступа, пользователь заблокирован (по умолчанию: 5 минут блокировки после 5 неудачных попыток доступа). Успешная проверка подлинности сбрасывает количество неудачных попыток доступа и обнуляет таймер. Максимальное количество неудачных попыток доступа и время блокировки можно задать с помощью MaxFailedAccessAttempts и DefaultLockoutTimeSpan. Следующие параметры настраивают блокировку учетной записи в течение 10 минут после 10 неудачных попыток доступа:

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

Убедитесь, что PasswordSignInAsync устанавливает lockoutOnFailure в true:

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