ASP.NET Core で TOTP 認証アプリ用の QR コードを生成できるようにする

ASP.NET Core には、個々の認証に対し認証アプリケーションのサポートが標準装備されています。 タイムベースのワンタイム パスワード アルゴリズム (TOTP) を使用する 2 要素認証 (2FA) 認証アプリは、業界で 2FA において推奨されるアプローチです。 TOTP を使用する 2FA は SMS 2FA より推奨されています。 認証アプリにより、ユーザー名とパスワードをユーザーが確認した後に入力する 6 から 8 桁のコードが提供されます。 通常、認証アプリはスマートフォンにインストールされています。

ASP.NET Core Web アプリ テンプレートでは認証システムはサポートしていますが、QR コードの生成はサポートしていません。 QR コード ジェネレーターを使用すると、2FA を簡単に設定できるようになります。 このドキュメントでは、2FA の構成ページに QR コードの生成を追加する方法について説明します。

2 要素認証は、GoogleFacebook などの外部認証プロバイダーを使用しては行われません。 外部ログインは、外部のログイン プロバイダーが提供するメカニズムによって保護されます。 たとえば、Microsoft 認証プロバイダーには、ハードウェア キーまたは別の 2FA アプローチが必要です。 一般的なシナリオではありませんが、既定のテンプレートで "ローカル" の 2FA が強制されている場合、ユーザーは 2 つの 2FA を満たす必要があります。

2FA 構成ページへの QR コードの追加

これらの手順では、 https://davidshimjs.github.io/qrcodejs/ リポジトリの qrcode.js を使用しています。

  • qrcode.js JavaScript ライブラリをご自分のプロジェクトの wwwroot\lib フォルダーにダウンロードします。
  • Identity のスキャフォールディングの指示に従って、/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml を生成します。
  • /Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml で、ファイルの末尾にある Scripts 探します。
@section Scripts {
    @await Html.PartialAsync("_ValidationScriptsPartial")
}
  • qr.js という新しい JavaScript ファイルを wwwroot/js に作成し、次のコードを追加して QR コードを生成します。
window.addEventListener("load", () => {
  const uri = document.getElementById("qrCodeData").getAttribute('data-url');
  new QRCode(document.getElementById("qrCode"),
    {
      text: uri,
      width: 150,
      height: 150
    });
});
  • Scripts セクションを更新して、前にダウンロードした qrcode.js ライブラリへの参照を追加します。
  • QR コードを生成する呼び出しを含む qr.js ファイルを追加します。
@section Scripts {
    @await Html.PartialAsync("_ValidationScriptsPartial")

    <script type="text/javascript" src="~/lib/qrcode.js"></script>
    <script type="text/javascript" src="~/js/qr.js"></script>
}
  • これらの手順にリンクされている段落を削除します。

アプリを実行し、QR コードをスキャンし、認証システムが証明するコードを検証できることを確認します。

QR コードのサイト名を変更する

QR コードのサイト名は、ご自分のプロジェクトを最初に作成したときに選択したプロジェクト名から取得されます。 これは、/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.csGenerateQrCodeUri(string email, string unformattedKey) メソッドを探すと変更できます。

テンプレートの既定のコードは次のようになります。

private string GenerateQrCodeUri(string email, string unformattedKey)
{
    return string.Format(
        AuthenticatorUriFormat,
        _urlEncoder.Encode("Razor Pages"),
        _urlEncoder.Encode(email),
        unformattedKey);
}

string.Format への呼び出しの 2 番目のパラメーターは、ご自分のソリューション名から取得したサイト名です。 これは任意の値に変更できますが、常にエンコードされた URL である必要があります。

別の QR コード ライブラリの使用

QR コード ライブラリは、お好みのライブラリに置き換えることができます。 HTML には、ご自分のライブラリが提供しているメカニズムを問わず QR コードを配置できる qrCode 要素があります。

正しい書式の QR コードの URL は、次にあります。

  • モデルの AuthenticatorUri プロパティ。
  • qrCodeData 要素の data-url プロパティ。

TOTP クライアントとサーバーの時間のずれ

TOTP (タイムベースのワンタイム パスワード) 認証は、サーバーと認証デバイスの両方の時間が正確であることに依存しています。 トークンは 30 秒間しか有効ではありません。 TOTP 2FA ログインが失敗する場合は、サーバーの時間が正確であり、できれば正確な NTP サービスに同期されていることを確認します。