ASP.NET Identity で二要素認証を使う - E-mail 編

ASP.NET Identity を使ってみようシリーズその3。

過去のシリーズは以下です。

その1 - ASP.NET Identity のセキュリティスタンプ機能を使う
その2 - ASP.NET Identity で二要素認証を使う - SMS 編

今日のお題

今回もみんな大好き二要素認証を実装してみましょう。

本日ご紹介するのは、メールでの二要素認証です。

前提

環境は Visual Studio 2013 Update 3 です。
ASP.NET MVC Web アプリケーションテンプレートからプロジェクトを作成します。

メールでの二要素認証

やることの大まかな流れは以下の通りです。

  • プロジェクトを作成
  • メール送信処理を書く
    • IIdentityMessageService インタフェースを実装するメール送信サービスを作成
    • メール送信サービスを UserManager クラスに登録
  • 二要素認証を利用するために画面を編集
    • テンプレートにすでに用意されているので、コメントを外すだけ

以上です。えっ?もしかして SMS メッセージ送信の時と同じ?

そうなんです。メッセージを送信するかメールを送信するかの違いはありますが、やってることは同じです。
なので、メッセージ送信による二要素認証と記述が大分被りますがご容赦ください(でもコピペじゃないんですよ!)。

はじめに

メッセージ送信の時と同じように、プロジェクトを作成/起動し、テスト用のユーザを登録します。

が、

メール送信による二要素認証を利用するためには、事前に Email Confirmation を行って、アプリにメールアドレスを確認させておく必要があります。

Email Confirmation を行う方法は ASP.NET Identity : E-Mail Confirmation - 松崎 剛 Blog をご確認いただければ。

もし既にテストユーザーを登録してしまっている場合は新しく作り直すか、登録済みのユーザーでも Email Confirmaion できるよう実装するか、もしくは DB を直接書き換えましょう。DB を書き換える場合、AspNetUsers テーブルの EmailConfirmed 列のフラグを立てればいいです。

メール送信処理を書く - IIdentityMessageService インタフェースを実装

では IIdentityMessageService インタフェースを実装していきます。

Microsoft.AspNet.Identity.IIdentityMessageService インタフェースや EmailServiceの説明は、、、まぁ大丈夫ですね?分からない方は ASP.NET Identity を使ってみようシリーズその2 をどうぞ。

なお、「はじめに」で説明したとおり、事前に Email Confirmation を行うためにメール送信処理を実装された方は、この項の作業は不要です。

さて。

SMTP サーバは Email Confirmation の記事に合わせて Azure の SendGrid を使いましょうか。

詳細は SendGrid を使用した Azure での電子メールの送信方法 - Microsoft Azure に丁寧に書いてありますが、コピペしても動きません。こまるよ! どうやらライブラリが更新されたらしく、API が変わっています。あきらめて自分で実装しましょう。

// App_Start\IdentityConfig.cs
public Task SendAsync(IdentityMessage message)
{
    // メールの作成
    var mailMessage = new SendGridMessage
    {
        From = new MailAddress("test@2fact.com"),
        To = new [] { new MailAddress(message.Destination) },
        Subject = message.Subject,
        Text = message.Body
    };

    // 資格情報の作成
    var username = "your_sendgrid_username";
    var pswd = "your_sendgrid_password";
    var credentials = new NetworkCredential(username, pswd);

    // メールの送信
    var transportWeb = new Web(credentials);
    transportWeb.Deliver(mailMessage);
    
    return Task.FromResult(0);
}

NuGet から SendGrid ライブラリ をインストールするのと、Azure に SendGrid アドオンを追加しておく必要があります。ユーザー名とパスワードをもらえるはずなので、↑ のコードを修正しておいてください。

メール送信処理を書く - メール送信サービスを登録

次に、作成したメール送信サービスを ASP.NET Identity に使ってもらえるよう登録します。

まぁこれもメッセージ送信の時と同じです。以下のコードで既に登録されています。

// App_Start\IdentityConfig.cs
manager.RegisterTwoFactorProvider("電子メール コード", new EmailTokenProvider<ApplicationUser>
{
    Subject = "セキュリティ コード",
    BodyFormat = "あなたのセキュリティ コードは {0} です。"
});
manager.EmailService = new EmailService();

二要素認証を利用するために画面を編集

ここもメッセージ送信の時と同じです。コードだけ載せておきます。

@* Views\Manage\Index.cshtml *@
<dt>2 要素認証:</dt>
<dd>
    @* 以下をコメントアウト
    <p>
        2 要素認証プロバイダーは構成されていません。2 要素認証がサポートされるようにこの ASP.NET アプリケーションを設定する方法の詳細については、
        <a href="http://go.microsoft.com/fwlink/?LinkId=313242">この記事</a>をご覧ください。
    </p>
    *@

    @* 以下のコメントを解除 *@ 
    @if (Model.TwoFactor)
    {

        <form method="post" action="/Manage/DisableTwoFactorAuthentication">
            有効
            <input type="submit" value="無効にする" class="btn btn-link" />
        </form>
    }
    else
    {

        <form method="post" action="/Manage/EnableTwoFactorAuthentication">
            無効
            <input type="submit" value="有効にする" class="btn btn-link" />
        </form>
    }
</dd>

実行!

これで準備は整いました。アカウント管理画面で二要素認証を有効化し、ログインし直してみましょう。

確認コードの入力画面が表示され、Confirm 済みのメールアドレスにセキュリティコード入りのメールが届きましたね?お疲れ様でした。

まとめ

昨日とおなじなので(ry