다음을 통해 공유


ASP.NET Core에서 SMS를 사용한 2단계 인증

릭 앤더슨 그리고 스위스-데브

경고

2FA(2단계 인증) 인증 앱은 시간 기반 TOTP(일회용 암호 알고리즘)를 사용하여 2FA에 대한 업계 권장 방법입니다. TOTP를 사용하는 2FA는 SMS 2FA에 선호됩니다. 자세한 내용은 ASP.NET Core 2.0 이상용 TOTP 인증자 앱을 위한 QR 코드 생성 사용 설정을 ASP.NET Core에서 참조하십시오.

이 자습서에서는 SMS를 사용하여 2FA(2단계 인증)를 설정하는 방법을 보여 줍니다. twilio 및 ASPSMS(https://www.aspsms.com/asp.net/identity/core/testcredits/)에 대한 지침이 제공되지만 다른 SMS 공급자를 사용할 수 있습니다. 이 자습서를 시작하기 전에 계정 확인 및 암호 복구 완료하는 것이 좋습니다.

샘플 코드보거나 다운로드합니다. 다운로드하는 방법 .

새 ASP.NET Core 프로젝트 만들기

개별 사용자 계정으로 Web2FA 새 ASP.NET Core 웹앱을 만듭니다. ASP.NET Core에서 HTTPS를 설정하고 강제 적용하려면 HTTPS를 강제 적용의 지침을 따르세요.

SMS 계정 만들기

예를 들어 twilio 또는 ASPSMS(https://www.aspsms.com/asp.net/identity/core/testcredits/)에서 SMS 계정을 만듭니다. 인증 자격 증명(twilio: accountSid 및 authToken, ASPSMS: Userkey 및 Password)을 기록합니다.

SMS 공급자 자격 증명 구성

트윌리오:

Twilio 계정의 대시보드 탭에서 계정 SID인증 토큰을(를) 복사하십시오.

asPSMS :

계정 설정에서 Userkey로 이동한 후, 암호와 함께 복사합니다.

나중에 secret-manager 도구를 사용하여 키 SMSAccountIdentificationSMSAccountPassword에 이러한 값을 저장합니다.

SenderID/Originator 지정

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, SMSAccountPasswordSMSAccountFrom 설정합니다. 예를 들어:

C:/Web2FA/src/WebApp1>dotnet user-secrets set SMSAccountIdentification 12345
info: Successfully saved SMSAccountIdentification = 12345 to the secret store.
  • SMS 공급자에 대한 NuGet 패키지를 추가합니다. PMC(패키지 관리자 콘솔)에서 다음을 실행합니다.

트윌리오:

Install-Package Twilio

asPSMS :

Install-Package ASPSMS

  • Services/MessageServices.cs 파일에 코드를 추가하여 SMS를 사용하도록 설정합니다. Twilio 또는 ASPSMS 섹션을 사용합니다.

트윌리오:

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 사용하도록 시작 구성

Startup.cs ConfigureServices 메서드의 서비스 컨테이너에 SMSoptions 추가합니다.

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

2단계 인증 사용

Views/Manage/Index.cshtml Razor 보기 파일을 열고 주석 문자를 제거합니다(태그가 주석 처리되지 않음).

2단계 인증으로 로그인

  • 앱 실행 및 새 사용자 등록

웹 애플리케이션 등록 보기가 Microsoft Edge 열립니다.

  • 사용자 이름을 탭하여 컨트롤러 관리에서 Index 작업 메서드를 활성화합니다. 그런 다음 전화 번호 추가 링크를 탭합니다.

보기 관리 - 탭합니다.

  • 확인 코드를 받을 전화 번호를 추가하고 확인 코드 보내기탭합니다.

전화 번호 추가 페이지

  • 확인 코드가 포함된 문자 메시지가 표시됩니다. 입력한 후 제출을(를) 누르세요.

전화 번호 확인 페이지

문자 메시지가 표시되지 않으면 twilio 로그 페이지를 참조하세요.

  • 관리 보기는 전화 번호가 성공적으로 추가되었음을 보여 줍니다.

보기 관리 - 전화 번호가 성공적으로 추가됨

  • 을(를) 탭하여 2단계 인증을 활성화합니다.

보기 관리 - 2단계 인증 사용 설정

2단계 인증 테스트

  • 로그오프합니다.

  • 로그인.

  • 사용자 계정이 2단계 인증을 사용하도록 설정했으므로 두 번째 인증 요소를 제공해야 합니다. 이 자습서에서는 전화 확인을 사용하도록 설정했습니다. 기본 제공 템플릿을 사용하면 전자 메일을 두 번째 요소로 설정할 수도 있습니다. QR 코드와 같은 인증에 대한 추가 두 번째 요소를 설정할 수 있습니다. 버튼을 누르고탭합니다.

확인 코드 전송

  • SMS 메시지에서 가져오는 코드를 입력합니다.

  • 이 브라우저 확인란을 클릭하면 동일한 디바이스 및 브라우저를 사용할 때 이중 인증(2FA)을 사용하여 로그인할 필요가 없습니다. 2FA를 사용하도록 설정하고 이 브라우저 기억하기를 클릭하면 디바이스에 접근할 수 없는 한 계정에 접근하려는 악의적인 사용자로부터 강력한 2FA 보호를 제공합니다. 정기적으로 사용하는 모든 개인 디바이스에서 이 작업을 수행할 수 있습니다. 이 브라우저 기억하기설정하면 정기적으로 사용하지 않는 디바이스에서 2FA의 보안이 강화되고, 사용자 고유의 디바이스에서 2FA를 거치지 않아도 되므로 편리하게 사용할 수 있습니다.

보기 확인

무차별 암호 대입 공격으로부터 보호하기 위한 계정 잠금

계정 잠금은 2FA를 사용하는 것이 좋습니다. 사용자가 로컬 계정 또는 소셜 계정을 통해 로그인하면 2FA에서 실패한 각 시도가 저장됩니다. 실패한 최대 액세스 시도에 도달하면 사용자가 잠깁니다(기본값: 5번의 액세스 시도 실패 후 5분 잠금). 인증에 성공하면 실패한 액세스 시도 횟수가 다시 설정되고 시계가 다시 설정됩니다. 최대 실패한 액세스 시도 및 잠금 시간은 MaxFailedAccessAttemptsDefaultLockoutTimeSpan사용하여 설정할 수 있습니다. 다음은 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);