Uwierzytelnianie dwuskładnikowe z wiadomością SMS w programie ASP.NET Core
Przez Rick Anderson i Swiss-Devs
Ostrzeżenie
Aplikacje do uwierzytelniania dwuskładnikowego (2FA), wykorzystujące algorytm jednorazowych haseł oparty na czasie (TOTP), są zalecanym w branży podejściem do 2FA. Uwierzytelnianie 2FA przy użyciu protokołu TOTP jest preferowane do uwierzytelniania SMS 2FA. Aby uzyskać więcej informacji, zobacz Włączanie generowania kodu QR dla aplikacji uwierzytelniania TOTP w ASP.NET Core dla ASP.NET Core 2.0 i nowszych wersji.
W tym samouczku pokazano, jak skonfigurować uwierzytelnianie dwuskładnikowe (2FA) za pomocą SMS. Instrukcje są podane dla twilio i ASPSMS (https://www.aspsms.com/asp.net/identity/core/testcredits/
), ale można użyć dowolnego innego dostawcy programu SMS. Zalecamy ukończenie potwierdzenia konta i odzyskiwania hasła przed rozpoczęciem tego samouczka.
Wyświetl lub pobierz przykładowy kod. Jak pobrać.
Tworzenie nowego projektu ASP.NET Core
Utwórz nową aplikację internetową platformy ASP.NET Core o nazwie Web2FA
przy użyciu poszczególnych kont użytkowników. Postępuj zgodnie z instrukcjami z sekcji Wymuszanie użycia HTTPS w ASP.NET Core, aby skonfigurować i wymusić protokół HTTPS.
Tworzenie konta SMS
Utwórz konto SMS, na przykład w usługach twilio lub ASPSMS (https://www.aspsms.com/asp.net/identity/core/testcredits/
). 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 Twojego konta Twilio skopiuj identyfikator SID konta oraz token uwierzytelniania.
ASPSMS:
W ustawieniach konta przejdź do Userkey i skopiuj go razem z Password.
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 numer telefonu usługi Twilio.
ASPSMS: W menu Odblokowywania Nadawców, odblokuj jednego lub więcej Nadawców lub wybierz alfanumeryczny Nadawcę (nie są obsługiwane przez wszystkie sieci).
Później zapiszemy tę wartość za pomocą narzędzia menedżera tajemnic w kluczu SMSAccountFrom
.
Podaj poświadczenia dla usługi SMS
Użyjemy wzorce opcji w celu uzyskania dostępu do konta użytkownika oraz kluczowych ustawień.
- Utwórz klasę, aby pobrać bezpieczny klucz SMS. W tym przykładzie klasa
SMSoptions
jest tworzona w plikuServices/SMSoptions.cs
.
namespace Web2FA.Services
{
public class SMSoptions
{
public string SMSAccountIdentification { get; set; }
public string SMSAccountPassword { get; set; }
public string SMSAccountFrom { get; set; }
}
}
Ustaw SMSAccountIdentification
, SMSAccountPassword
i SMSAccountFrom
za pomocą narzędzia secret-manager. Na 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żera 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);
}
}
}
Skonfiguruj uruchamianie, aby używać SMSoptions
Dodaj SMSoptions
do kontenera usługi w metodzie ConfigureServices
w Startup.cs
:
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
services.Configure<SMSoptions>(Configuration);
}
Włączanie uwierzytelniania dwuskładnikowego
Otwórz plik widoku Views/Manage/Index.cshtml
Razor 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
- Naciśnij nazwę użytkownika, która aktywuje metodę akcji
Index
w obszarze Zarządzanie kontrolerem. Następnie naciśnij numer telefonu Dodaj link.
- Dodaj numer telefonu, który otrzyma kod weryfikacyjny, a następnie naciśnij pozycję Wyślij kod weryfikacyjny.
- Otrzymasz wiadomość SMS z kodem weryfikacyjnym. Wprowadź go i naciśnij Prześlij
Jeśli nie otrzymasz wiadomości SMS, zobacz stronę dziennika usługi twilio.
- Widok Zarządzaj pokazuje, że numer telefonu został dodany pomyślnie.
widok zarządzania
- Stuknij Włącz, aby włączyć uwierzytelnianie dwuskładnikowe.
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 czynniki weryfikacji dwuetapowej na potrzeby uwierzytelniania, takie jak kody QR. Naciśnij Prześlij.
Wprowadź kod otrzymany w wiadomości SMS.
Kliknięcie na pole wyboru Zapamiętaj tę przeglądarkę sprawi, że nie będzie konieczności używania uwierzytelniania 2FA podczas logowania się, jeśli korzystasz z tego samego urządzenia i przeglądarki. Włączenie uwierzytelniania 2FA i kliknięcie na Zapamiętaj tę przeglądarkę zapewni użytkownikowi silną ochronę 2FA przed złośliwymi użytkownikami próbującymi uzyskać dostęp do jego konta, pod warunkiem, że nie mają dostępu do jego urządzenia. Można to zrobić na dowolnym urządzeniu prywatnym, którego regularnie używasz. Ustawiając Zapamiętaj tę przeglądarkę, uzyskujesz dodatkowe zabezpieczenia dzięki 2FA na urządzeniach, których nie używasz regularnie, i masz wygodę, że nie musisz przechodzić przez uwierzytelnianie 2FA na własnych urządzeniach.
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ć przy użyciu MaxFailedAccessAttempts 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 ustawia lockoutOnFailure
na true
:
var result = await _signInManager.PasswordSignInAsync(
Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true);