Partilhar via


Autenticação de dois fatores com SMS no ASP.NET Core

Por Rick Anderson e Swiss-Devs

Warning

Os aplicativos autenticadores de autenticação de dois fatores (2FA), usando um algoritmo de senha única (TOTP) baseado em tempo, são a abordagem recomendada pelo setor para o 2FA. 2FA usando TOTP é preferível ao SMS 2FA. Para obter mais informações, consulte Habilitar a geração de código QR para aplicativos autenticadores TOTP no ASP.NET Core para ASP.NET Core 2.0 ou posterior.

Este tutorial mostra como configurar a autenticação de dois fatores (2FA) usando o SMS. As instruções são dadas para twilio e ASPSMS (https://www.aspsms.com/asp.net/identity/core/testcredits/), mas você pode usar qualquer outro provedor de SMS. Recomendamos que complete a Confirmação de Conta e a Recuperação de Senha antes de iniciar este tutorial.

Ver ou transferir código de exemplo. Como descarregar.

Criar um novo projeto ASP.NET Core

Crie um novo aplicativo Web ASP.NET Core nomeado Web2FA com contas individuais. Siga as instruções em Impor HTTPS no ASP.NET Core para configurar e exigir HTTPS.

Criar uma conta SMS

Crie uma conta SMS, por exemplo, a partir de twilio ou ASPSMS (https://www.aspsms.com/asp.net/identity/core/testcredits/). Registre as credenciais de autenticação (para twilio: accountSid e authToken, para ASPSMS: Userkey e Password).

Descobrindo as credenciais do provedor de SMS

Twilio:

Na guia Painel da sua conta Twilio, copie o SID da Conta e o Auth token.

ASPSMS:

Nas definições da sua conta, navegue até Chave de Utilizador e copie-a juntamente com a sua Palavra-passe .

Mais tarde, armazenaremos esses valores com a ferramenta secret-manager dentro das chaves SMSAccountIdentification e SMSAccountPassword.

Especificando ID do Remetente / Origem

Twilio: Na guia Números, copie seu número de telefone do Twilio .

ASPSMS: No menu Desbloquear originadores, desbloqueie um ou mais originadores ou escolha um originador alfanumérico (não suportado por todas as redes).

Mais tarde, armazenaremos essa valor com a ferramenta secret-manager dentro da chave SMSAccountFrom.

Fornecer credenciais para o serviço de SMS

Usaremos o padrão de Opções para acessar a conta de usuário e as configurações de chave.

  • Crie uma classe para buscar a chave SMS segura. Para este exemplo, a classe SMSoptions é criada no arquivo Services/SMSoptions.cs.
namespace Web2FA.Services
{
    public class SMSoptions
    {
        public string SMSAccountIdentification { get; set; }
        public string SMSAccountPassword { get; set; }
        public string SMSAccountFrom { get; set; }
    }
}

Defina o SMSAccountIdentification, SMSAccountPassword e SMSAccountFrom com a ferramenta de gestão de segredos . Por exemplo:

C:/Web2FA/src/WebApp1>dotnet user-secrets set SMSAccountIdentification 12345
info: Successfully saved SMSAccountIdentification = 12345 to the secret store.
  • Adicione o pacote NuGet para o provedor de SMS. Na Consola do Gestor de Pacotes (PMC), execute:

Twilio:

Install-Package Twilio

ASPSMS:

Install-Package ASPSMS

  • Adicione código no arquivo Services/MessageServices.cs para habilitar o SMS. Use a seção 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);
        }
    }
}

Configurar a inicialização para usar SMSoptions

Adicione SMSoptions ao contêiner de serviço no método ConfigureServices no Startup.cs:

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

Habilitar autenticação de dois fatores

Abra o arquivo de visualização Views/Manage/Index.cshtmlRazor e remova os caracteres de comentário (para que nenhuma marcação seja comentada).

Faça login com autenticação de dois fatores

  • Execute o aplicativo e registre um novo usuário

Vista de registo da aplicação Web aberta no Microsoft Edge

  • Toque no seu nome de usuário, que ativa o método de ação Index em Gerenciar controlador. Em seguida, toque no número de telefone Adicionar o link.

Gerir visualização - toque no link

  • Adicione um número de telefone que receberá o código de verificação e toque em Enviar código de verificação.

página Adicionar Número de Telefone

  • Você receberá uma mensagem de texto com o código de verificação. Introduza-o e toque Enviar

página de Verificação do Número de Telefone

Se você não receber uma mensagem de texto, consulte a página de log do twilio.

  • A vista Gerir mostra que o seu número de telefone foi adicionado com êxito.

Gerir visualização - número de telefone adicionado com êxito

  • Toque Ativar para ativar a autenticação de dois fatores.

Gerir visualização - habilitar autenticação de dois fatores

Testar autenticação de dois fatores

  • Faça logoff.

  • Iniciar sessão.

  • A conta de usuário habilitou a autenticação de dois fatores, portanto, você precisa fornecer o segundo fator de autenticação. Neste tutorial, você habilitou a verificação por telefone. Os modelos embutidos também permitem que você configure o e-mail como o segundo fator. Você pode configurar segundos fatores adicionais para autenticação, como códigos QR. Toque em Enviar.

Enviar visualização de código de verificação

  • Introduza o código que recebe na mensagem SMS.

  • Clicar na caixa de seleção Lembre-se deste navegador irá isentá-lo da necessidade de usar 2FA para fazer logon ao usar o mesmo dispositivo e navegador. Ao ativar o 2FA e clicar em Lembre-se deste navegador, fornecerá proteção robusta de 2FA contra utilizadores mal-intencionados que tentam aceder à sua conta, desde que não tenham acesso ao seu dispositivo. Pode fazê-lo em qualquer dispositivo privado que utilize regularmente. Ao definir Lembrar este navegador, obténs a segurança adicional da autenticação de dois fatores em dispositivos que não usas regularmente e a conveniência de não ter de passar pela autenticação de dois fatores nos teus próprios dispositivos.

Verificar vista

Bloqueio de conta para proteção contra ataques de força bruta

Recomenda-se o bloqueio de conta com autenticação de dois fatores. Quando um utilizador inicia sessão através de uma conta local ou conta social, cada tentativa falhada de 2FA é armazenada. Se o máximo de tentativas de acesso com falha for atingido, o usuário será bloqueado (padrão: bloqueio de 5 minutos após 5 tentativas de acesso com falha). Uma autenticação bem-sucedida redefine a contagem de tentativas de acesso com falha e redefine o relógio. O máximo de tentativas de acesso com falha e o tempo de bloqueio podem ser definidos com MaxFailedAccessAttempts e DefaultLockoutTimeSpan. O seguinte configura o bloqueio de conta por 10 minutos após 10 tentativas de acesso com falha:

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

Confirme se PasswordSignInAsync define lockoutOnFailure para true:

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