ASP.NET Core での SMS による2要素認証Two-factor authentication with SMS in ASP.NET Core

By Rick Anderson および スイス-開発者By Rick Anderson and Swiss-Devs

警告

2要素認証 (2FA) 認証アプリは、時間ベースのワンタイムパスワードアルゴリズム (TOTP) を使用して、2FA に業界で推奨されるアプローチです。Two factor authentication (2FA) authenticator apps, using a Time-based One-time Password Algorithm (TOTP), are the industry recommended approach for 2FA. TOTP を使用した2FA は、SMS 2FA に適しています。2FA using TOTP is preferred to SMS 2FA. 詳細については、ASP.NET Core 2.0 以降の ASP.NET Core での TOTP authenticator アプリの QR コード生成の有効化 に関する説明を参照してください。For more information, see Enable QR Code generation for TOTP authenticator apps in ASP.NET Core for ASP.NET Core 2.0 and later.

このチュートリアルでは、SMS を使用して2要素認証 (2FA) を設定する方法について説明します。This tutorial shows how to set up two-factor authentication (2FA) using SMS. 手順については、 twilioaspsmsを参照してください。ただし、他の sms プロバイダーを使用することもできます。Instructions are given for twilio and ASPSMS, but you can use any other SMS provider. このチュートリアルを開始する前に 、アカウントの確認とパスワードの回復 を完了することをお勧めします。We recommend you complete Account Confirmation and Password Recovery before starting this tutorial.

サンプル コードを表示またはダウンロードします。View or download sample code. ダウンロード方法How to download.

新しい ASP.NET Core プロジェクトを作成するCreate a new ASP.NET Core project

Web2FA個々のユーザーアカウントを使用して、という名前の新しい ASP.NET Core web アプリを作成します。Create a new ASP.NET Core web app named Web2FA with individual user accounts. 「」の手順に従っ ASP.NET Core に HTTPS を適用する て、HTTPS を設定し、要求します。Follow the instructions in ASP.NET Core に HTTPS を適用する to set up and require HTTPS.

SMS アカウントの作成Create an SMS account

たとえば、 twilioASPSMSなどの sms アカウントを作成します。Create an SMS account, for example, from twilio or ASPSMS. 認証資格情報 (ASPSMS の場合は twilio: accountSid および authToken の場合はユーザーキーとパスワード) を記録します。Record the authentication credentials (for twilio: accountSid and authToken, for ASPSMS: Userkey and Password).

SMS プロバイダーの資格情報の確認Figuring out SMS Provider credentials

TwilioTwilio:

Twilio アカウントの [ダッシュボード] タブで、 アカウント SID認証トークン をコピーします。From the Dashboard tab of your Twilio account, copy the Account SID and Auth token .

ASPSMS:ASPSMS:

アカウントの設定から ユーザーキー に移動し、 パスワード と共にコピーします。From your account settings, navigate to Userkey and copy it together with your Password .

これらの値は、後で、キーと内の secret manager ツールを使用してに格納し SMSAccountIdentification SMSAccountPassword ます。We will later store these values in with the secret-manager tool within the keys SMSAccountIdentification and SMSAccountPassword.

SenderID/オリジネータの指定Specifying SenderID / Originator

Twilio: [数値] タブで、Twilio 電話番号 をコピーします。Twilio: From the Numbers tab, copy your Twilio phone number .

Aspsms: [発信元のロック解除] メニュー内で、1つ以上の発信者をロック解除するか、英数字の発信者を選択します (すべてのネットワークでサポートされていません)。ASPSMS: Within the Unlock Originators Menu, unlock one or more Originators or choose an alphanumeric Originator (Not supported by all networks).

この値は、後でキー内にシークレットマネージャーツールで格納し SMSAccountFrom ます。We will later store this value with the secret-manager tool within the key SMSAccountFrom.

SMS サービスの資格情報を指定するProvide credentials for the SMS service

オプションパターンを使用して、ユーザーアカウントとキーの設定にアクセスします。We'll use the Options pattern to access the user account and key settings.

  • セキュリティで保護された SMS キーを取得するクラスを作成します。Create a class to fetch the secure SMS key. このサンプルでは、 SMSoptions サービス/smsoptions .cs ファイルにクラスを作成します。For this sample, the SMSoptions class is created in the Services/SMSoptions.cs file.
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 ツールを使用して設定します。Set the SMSAccountIdentification, SMSAccountPassword and SMSAccountFrom with the secret-manager tool. 次に例を示します。For example:

C:/Web2FA/src/WebApp1>dotnet user-secrets set SMSAccountIdentification 12345
info: Successfully saved SMSAccountIdentification = 12345 to the secret store.
  • SMS プロバイダーの NuGet パッケージを追加します。Add the NuGet package for the SMS provider. パッケージマネージャーコンソール (PMC) から次のように実行します。From the Package Manager Console (PMC) run:

TwilioTwilio:

Install-Package Twilio

ASPSMS:ASPSMS:

Install-Package ASPSMS

  • サービス/MessageServices .cs ファイルにコードを追加して、SMS を有効にします。Add code in the Services/MessageServices.cs file to enable SMS. Twilio または ASPSMS セクションのいずれかを使用します。Use either the Twilio or the ASPSMS section:

TwilioTwilio:

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

使用するスタートアップの構成 SMSoptionsConfigure startup to use SMSoptions

SMSoptionsStartup.cs のメソッドで、サービスコンテナーにを追加し ConfigureServices ます。 Startup.csAdd SMSoptions to the service container in the ConfigureServices method in the Startup.cs :

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

2 要素認証を有効にするEnable two-factor authentication

Views/Manage/Index. cshtml Razor ビューファイルを開き、コメント文字を削除します (マークアップがコメントアウトされることはありません)。Open the Views/Manage/Index.cshtml Razor view file and remove the comment characters (so no markup is commented out).

2要素認証を使用してログインするLog in with two-factor authentication

  • アプリを実行して新しいユーザーを登録するRun the app and register a new user

Microsoft Edge で開いている Web アプリケーション登録ビュー

  • [コントローラーの管理] でアクションメソッドをアクティブにするユーザー名をタップし Index ます。Tap on your user name, which activates the Index action method in Manage controller. 次に、[電話番号の 追加 ] リンクをタップします。Then tap the phone number Add link.

[管理] の [追加] リンク

  • 確認コードを受信する電話番号を追加し、[ 確認コードの送信 ] をタップします。Add a phone number that will receive the verification code, and tap Send verification code .

[電話番号の追加] ページ

  • 確認コードを含むテキストメッセージが表示されます。You will get a text message with the verification code. 入力し、[ 送信 ] をタップします。Enter it and tap Submit

[電話番号の確認] ページ

テキストメッセージが表示されない場合は、「twilio log page」を参照してください。If you don't get a text message, see twilio log page.

  • 管理ビューには、電話番号が正常に追加されたことが表示されます。The Manage view shows your phone number was added successfully.

ビューの管理-電話番号が正常に追加されました

  • [ 有効 ] をタップして、2要素認証を有効にします。Tap Enable to enable two-factor authentication.

ビューの管理-2 要素認証の有効化

2要素認証をテストするTest two-factor authentication

  • ログオフします。Log off.

  • ログインします。Log in.

  • ユーザーアカウントで2要素認証が有効になっているため、2番目の認証要素を指定する必要があります。The user account has enabled two-factor authentication, so you have to provide the second factor of authentication . このチュートリアルでは、電話による検証を有効にしました。In this tutorial you have enabled phone verification. 組み込みのテンプレートでは、2番目の要素として電子メールを設定することもできます。The built in templates also allow you to set up email as the second factor. QR コードなどの認証については、さらに2つ目の要素を設定できます。You can set up additional second factors for authentication such as QR codes. [ Submit (送信 )」をタップします。Tap Submit .

確認コードビューの送信

  • SMS メッセージで取得したコードを入力します。Enter the code you get in the SMS message.

  • [ このブラウザーを記憶 する] チェックボックスをオンにすると、同じデバイスとブラウザーを使用しているときに2fa を使用してログオンする必要がありません。Clicking on the Remember this browser check box will exempt you from needing to use 2FA to log on when using the same device and browser. 2FA を有効にして [ このブラウザーを記憶 する] をオンにすると、悪意のあるユーザーが自分のデバイスにアクセスできなくても、アカウントへのアクセスを試みる悪意のあるユーザーからの強力な2fa 保護が提供されます。Enabling 2FA and clicking on Remember this browser will provide you with strong 2FA protection from malicious users trying to access your account, as long as they don't have access to your device. この操作は、定期的に使用するプライベートデバイスで行うことができます。You can do this on any private device you regularly use. [ このブラウザーを記憶 する] を設定すると、定期的に使用しないデバイスから2fa のセキュリティが強化され、自分のデバイスで2fa を通過する必要がなくなります。By setting Remember this browser , you get the added security of 2FA from devices you don't regularly use, and you get the convenience on not having to go through 2FA on your own devices.

ビューの確認

ブルートフォース攻撃から保護するためのアカウントロックアウトAccount lockout for protecting against brute force attacks

アカウントのロックアウトは2FA で推奨されます。Account lockout is recommended with 2FA. ユーザーがローカルアカウントまたはソーシャルアカウントを使用してサインインすると、2FA に失敗した各操作が格納されます。Once a user signs in through a local account or social account, each failed attempt at 2FA is stored. 失敗したアクセス試行の最大回数に達した場合、ユーザーはロックアウトされます (既定では5分間のロックアウトが失敗し、アクセス試行が5回失敗します)。If the maximum failed access attempts is reached, the user is locked out (default: 5 minute lockout after 5 failed access attempts). 認証が成功すると、失敗したアクセス試行回数がリセットされ、時計がリセットされます。A successful authentication resets the failed access attempts count and resets the clock. 失敗したアクセス試行の最大回数とロックアウト時間は、 Maxfailed AccessattemptsDefaultlockouttimespanで設定できます。The maximum failed access attempts and lockout time can be set with MaxFailedAccessAttempts and DefaultLockoutTimeSpan. 次の例では、10分間に失敗したアクセス試行の10分後にアカウントのロックアウトを構成します。The following configures account lockout for 10 minutes after 10 failed access attempts:

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 ます。Confirm that PasswordSignInAsync sets lockoutOnFailure to true:

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