ASP.NET MVC 5 アプリで SMS と電子メール Two-Factor 認証を使用する
作成者: Rick Anderson
このチュートリアルでは、2 要素認証を使用して ASP.NET MVC 5 Web アプリを構築する方法について説明します。 続行する前に、「ログイン、電子メール確認、パスワード リセットを使用して安全な ASP.NET MVC 5 Web アプリを作成する」を完了する必要があります。 完成したアプリケーションはこちらからダウンロードできます。 ダウンロードには、電子メールまたは SMS プロバイダーを設定せずに電子メールの確認と SMS をテストできるデバッグ ヘルパーが含まれています。
このチュートリアルは Rick Anderson (Twitter: @RickAndMSFT) によって作成されました。
ASP.NET MVC アプリを作成する
まず、Visual Studio Express 2013 for Web 以降をインストールして実行します。
メモ
警告: 続行する前に、「ログイン、電子メール確認、パスワード リセットを使用して安全な ASP.NET MVC 5 Web アプリを作成する」を完了する必要があります。 このチュートリアルを完了するには、Visual Studio 2013 Update 3 以降をインストールする必要があります。
- 新しい ASP.NET Web プロジェクトを作成し、MVC テンプレートを選択します。 Web フォームでは ASP.NET ID もサポートされているため、Web フォーム アプリでも同様の手順を実行できます。
- 既定の認証は [個人ユーザー アカウント] のままにします。 Azure でアプリをホストする場合は、チェック ボックスをオンのままにします。 チュートリアルの後半で Azure にデプロイします。 Azure アカウントの開設は無料です。
- SSL を使用するようにプロジェクトを設定します。
2 要素認証用に SMS を設定する
このチュートリアルでは、Twilio または ASPSMS を使用する手順を説明しますが、他の SMS プロバイダーも使用できます。
SMS プロバイダーを使用したユーザー アカウントの作成
追加パッケージのインストールまたはサービス参照の追加
Twilio:
パッケージ マネージャー コンソールで、次のコマンドを入力します。
Install-Package Twilio
ASPSMS:
次のサービス参照を追加する必要があります。Address:
https://webservice.aspsms.com/aspsmsx2.asmx?WSDL
名前空間:
ASPSMSX2
SMS プロバイダーのユーザー資格情報の把握
最も安全な認証オプションを使用することをお勧めします。 Azure にデプロイされた .NET アプリについては、次を参照してください。
Azure Key Vault と .NET Aspire は、シークレットを格納および取得するための最も安全な方法を提供します。 Azure Key Vault は、暗号化キーとシークレット (証明書、接続文字列、パスワードなど) を保護するクラウド サービスです。 .NET アスパイアについては、「ホスティングとクライアント統合の間のセキュリティで保護された通信を参照してください。
リソース所有者のパスワード資格情報の付与は、次の理由で回避してください。
- ユーザーのパスワードをクライアントに公開します。
- これは重大なセキュリティ上のリスクです。
- 他の認証フローが不可能な場合にのみ使用してください。
アプリがテスト サーバーにデプロイされると、環境変数を使用して接続文字列をテスト データベース サーバーに設定できます。 環境変数は、通常、暗号化されていないプレーンテキストで格納されます。 コンピューターまたはプロセスが侵害された場合、信頼されていないパーティーが環境変数にアクセスできるようになります。 最も安全な方法ではないため、環境変数を使用して本番接続文字列を格納しないことをお勧めします。
構成データのガイドライン:
- 構成プロバイダーのコードやプレーンテキストの構成ファイルには、パスワードなどの機密データを格納しないでください。
- 開発環境やテスト環境では運用シークレットを使用しないでください。
- プロジェクトの外部にシークレットを指定してください。そうすれば、誤ってリソース コード リポジトリにコミットされることはありません。
Twilio:
Twilio アカウントの [ダッシュボード] タブで、アカウント SID をコピーし、認証トークンをコピーします。
ASPSMS:
アカウント設定から [Userkey] に移動し、自分で定義したパスワードと一緒にコピーします。
これらの値は、後でキー "SMSAccountIdentification"
および "SMSAccountPassword"
内の web.config ファイルに格納します。
4. 送信者ID/起点を指定する
Twilio:
[番号] タブで Twilio の電話番号をコピーします。
ASPSMS:
[発信元のロック解除] メニューで、1 つ以上の発信元のロックを解除するか、英数字の発信元を選択します (すべてのネットワークでサポートされているわけではありません)。
この値は、後でキー "SMSAccountFrom"
内の web.config ファイルに格納します。
5. SMS プロバイダーの資格情報をアプリ に転送する
アプリで資格情報と送信者の電話番号を使用できるようにします。 わかりやすくするために、これらの値を web.config ファイルに格納します。 Azure にデプロイする際に、Web サイトの構成タブのアプリ設定セクションに値を安全に格納できます。
[!code-xml[Main](aspnet-mvc-5-app-with-sms-and-email-two-factor-authentication/samples/sample1.xml?highlight=8-10)]
> [!WARNING]
> Security - Never store sensitive data in your source code. The account and credentials are added to the code above to keep the sample simple. See [Best practices for deploying passwords and other sensitive data to ASP.NET and Azure](../../../identity/overview/features-api/best-practices-for-deploying-passwords-and-other-sensitive-data-to-aspnet-and-azure.md).
SMS プロバイダーへのデータ転送の実装
App_Start\IdentityConfig.cs ファイルで
SmsService
クラスを構成します。使用される SMS プロバイダーに応じて、[Twilio] または [ASPSMS] セクションをアクティブ化します。
public class SmsService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { // Twilio Begin //var accountSid = ConfigurationManager.AppSettings["SMSAccountIdentification"]; //var authToken = ConfigurationManager.AppSettings["SMSAccountPassword"]; //var fromNumber = ConfigurationManager.AppSettings["SMSAccountFrom"]; //TwilioClient.Init(accountSid, authToken); //MessageResource result = MessageResource.Create( //new PhoneNumber(message.Destination), //from: new PhoneNumber(fromNumber), //body: message.Body //); ////Status is one of Queued, Sending, Sent, Failed or null if the number is not valid //Trace.TraceInformation(result.Status.ToString()); ////Twilio doesn't currently have an async API, so return success. //return Task.FromResult(0); // Twilio End // ASPSMS Begin // var soapSms = new MvcPWx.ASPSMSX2.ASPSMSX2SoapClient("ASPSMSX2Soap"); // soapSms.SendSimpleTextSMS( // System.Configuration.ConfigurationManager.AppSettings["SMSAccountIdentification"], // System.Configuration.ConfigurationManager.AppSettings["SMSAccountPassword"], // message.Destination, // System.Configuration.ConfigurationManager.AppSettings["SMSAccountFrom"], // message.Body); // soapSms.Close(); // return Task.FromResult(0); // ASPSMS End } }
Views\Manage\Index.cshtml Razor ビューを更新します (注: 終了コードのコメントを削除するだけでなく、次のコードを使用してください)。
@model MvcPWy.Models.IndexViewModel @{ ViewBag.Title = "Manage"; } <h2>@ViewBag.Title.</h2> <p class="text-success">@ViewBag.StatusMessage</p> <div> <h4>Change your account settings</h4> <hr /> <dl class="dl-horizontal"> <dt>Password:</dt> <dd> [ @if (Model.HasPassword) { @Html.ActionLink("Change your password", "ChangePassword") } else { @Html.ActionLink("Create", "SetPassword") } ] </dd> <dt>External Logins:</dt> <dd> @Model.Logins.Count [ @Html.ActionLink("Manage", "ManageLogins") ] </dd> <dt>Phone Number:</dt> <dd> @(Model.PhoneNumber ?? "None") [ @if (Model.PhoneNumber != null) { @Html.ActionLink("Change", "AddPhoneNumber") @: | @Html.ActionLink("Remove", "RemovePhoneNumber") } else { @Html.ActionLink("Add", "AddPhoneNumber") } ] </dd> <dt>Two-Factor Authentication:</dt> <dd> @if (Model.TwoFactor) { using (Html.BeginForm("DisableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <text>Enabled <input type="submit" value="Disable" class="btn btn-link" /> </text> } } else { using (Html.BeginForm("EnableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <text>Disabled <input type="submit" value="Enable" class="btn btn-link" /> </text> } } </dd> </dl> </div>
ManageController
のEnableTwoFactorAuthentication
およびDisableTwoFactorAuthentication
アクション メソッドに [ValidateAntiForgeryToken] 属性があることを確認します。// // POST: /Manage/EnableTwoFactorAuthentication [HttpPost,ValidateAntiForgeryToken] public async Task<ActionResult> EnableTwoFactorAuthentication() { await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true); var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); if (user != null) { await SignInAsync(user, isPersistent: false); } return RedirectToAction("Index", "Manage"); } // // POST: /Manage/DisableTwoFactorAuthentication [HttpPost, ValidateAntiForgeryToken] public async Task<ActionResult> DisableTwoFactorAuthentication() { await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), false); var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); if (user != null) { await SignInAsync(user, isPersistent: false); } return RedirectToAction("Index", "Manage"); }
アプリを実行し、以前に登録したアカウントでログインします。
ユーザー ID をクリックすると、
Index
コントローラー内のManage
アクション メソッドがアクティブになります。
[追加] をクリックします。
AddPhoneNumber
アクション メソッドは、SMS メッセージを受信できる電話番号を入力するダイアログ ボックスを表示します。// GET: /Account/AddPhoneNumber public ActionResult AddPhoneNumber() { return View(); }
数秒後に、確認コードを含むテキスト メッセージが届きます。 それを入力し、「送信」を押します。
[管理] ビューには電話番号が追加されたことが表示されます。
2 要素認証を有効にする
テンプレートで生成されたアプリでは、UI を使用して 2 要素認証 (2FA) を有効にする必要があります。 2FA を有効にするには、ナビゲーション バーでユーザー ID (電子メール エイリアス) をクリックします。
[2FA を有効にする] をクリックします。
ログアウトしてからもう一度ログインします。 電子メールを有効にしている場合 (前のチュートリアルを参照)、2FA 用の SMS または電子メールを選択できます。
[コードの確認] ページが表示され、ここで (SMS または電子メールに記載されている) コードを入力できます。
[このブラウザーを記憶する] チェックボックスをオンにすると、このチェックボックスがオンになっているブラウザーとデバイスでは、2FA を使用せずにログインできます。 悪意のあるユーザーがデバイスにアクセスできない限り、2FA を有効にし、このブラウザーを記憶する をクリックすることで、信頼されていないデバイスからのすべてのアクセスに対して強力な 2FA 保護を維持しつつ、便利なワンステップパスワードアクセスを提供します。 これは、定期的に使用するすべてのプライベート デバイスで実行できます。
このチュートリアルでは、新しい ASP.NET MVC アプリで 2FA を有効にする方法について簡単に説明します。 私のチュートリアル「ASP.NET Identity で SMS と電子メールを利用して 2 要素認証を行う」では、サンプルの背後にあるコードについて詳しく説明しています。
その他のリソース
- 「ASP.NET Identity で SMS と電子メールを利用して 2 要素認証を行う」では 2 要素認証について詳しく説明しています
- ASP.NET Identity 推奨リソースへのリンク
- 「ASP.NET Identity でのアカウントの確認とパスワードの回復」ではパスワードの回復とアカウントの確認について詳しく説明しています。
- Facebook、Twitter、LinkedIn、Google の OAuth2 サインオンを使用した MVC 5 アプリ このチュートリアルでは、Facebook と Google の OAuth 2 認証を使用した ASP.NET MVC 5 アプリを作成する方法について説明します。 ID データベースにデータを追加する方法も説明しています。
- メンバーシップ、OAuth、SQL データベースを使用した安全な ASP.NET MVC アプリの Azure Web へのデプロイ。 このチュートリアルでは、Azure デプロイの追加方法、ロールを使用してアプリをセキュリティで保護する方法、メンバーシップ API を使用してユーザーとロールを追加する方法、および追加のセキュリティ機能について説明します。
- OAuth 2 用 Google アプリを作成し、そのアプリをプロジェクトに接続する
- Facebook でアプリを作成し、そのアプリをプロジェクトに接続する
- プロジェクトで SSL を設定する
- C# と ASP.NET MVC 開発環境をセットアップする方法