0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Auth0で学ぶ認証強化】Auth0 ActionsでMFAを出し分ける(PasskeyならMFAスキップ、ID/パスワードならMFA要求)

0
Posted at

はじめに

前回、Auth0公式ReactクイックスタートにMFA(多要素認証)を追加してみたという記事で、「ログイン強化編」の2回目として、ログインのたびに常にMFAを要求する設定を試しました。

ただ、実際のサービスでは「全ユーザーに常にMFAを要求する」のはやや過剰で、ユーザー体験を損ねがちです。特に、前々回で追加したPasskeyは、生体認証とデバイス固有の鍵ペアによってフィッシング耐性を備えた認証方式であり、それ自体がすでに「もう一つの要素」に相当するとも言えます。

そこで今回は、Auth0 Actions を使って、ログイン方法に応じてMFAの要求を出し分けてみます。具体的には、

  • Passkeyでログインした場合 → MFAをスキップ
  • ID/パスワードでログインした場合 → MFAを要求

という条件分岐を実装します。これは認証後に実行されるAction(Post-Loginトリガー)の中で、「どの認証方法でログインしたか」というコンテキストを使って、MFAを要求するかどうかを動的に決める仕組みです。Auth0公式でも「Reduce friction with passkeys」というユースケースとして紹介されているパターンです。

※こちらの手順は2026年10月時点のものとなります。


事前準備

  • 前回・前々回で作成したReactアプリ(auth0-react-quickstart)
  • Passkeyが有効化されたAuth0のデータベース接続(前々回の記事参照)
  • MFA(TOTPなど)が有効化されたAuth0テナント(前回の記事参照)

今回はダッシュボードの設定だけでなく、初めてActions(Node.jsのコード)を書きます。


1. 「ActionsでMFA要素をカスタマイズする」を有効化する

Actionsから api.multifactor.enable("none") などを呼び出してMFAの要求を制御するには、まずこの機能をダッシュボード側で有効にしておく必要があります。

  1. Auth0ダッシュボードの左メニューから 「セキュリティ」→「多要素認証」 を選択します。
    多要素認証

  2. 画面下部の 「追加設定」 を開き、「ActionsでMFA要素をカスタマイズする」 のトグルを ON にします。
    追加設定

これで、Actions側からMFAの要求有無をコントロールできるようになりました。


2. Actionを作成する

  1. Auth0ダッシュボードの左メニューから 「アクション」→「ライブラリー」 を選択します。その後、カスタムタブの 「アクションの作成」 をクリックします。
    アクションの作成

  2. 初めから構築する を選択し、適当な名前(例: skip-mfa-for-passkey)、トリガーは 「Login / Post Login」 を選択し、ランタイムはNode 22 を選択して作成します。
    設定

  3. エディタに以下のコードを記述します。

    /**
     * @param {Event} event - ログインしたユーザーとコンテキストの情報
     * @param {PostLoginAPI} api - ログイン後の挙動を変更するためのAPI
     */
    exports.onExecutePostLogin = async (event, api) => {
      // 今回の認証でPasskeyが使われたかどうかを判定する
      const usedPasskey = event.authentication?.methods.some(
        (method) => method.name === "passkey"
      );
    
      // Passkeyでログインしていた場合はMFAをスキップする
      if (usedPasskey) {
        api.multifactor.enable("none");
      }
    
      // ID/パスワードなど他の方法でログインした場合は何もしない
      // → テナントに設定済みの「常時」ポリシーがそのまま適用される
    };
    

    event.authentication.methods には、今回のログインで使われた認証方法の履行履歴が配列で入っています。name が "passkey" であれば、Passkeyでログインしたことがわかります。Passkeyが使われていた場合のみ api.multifactor.enable("none") を呼び、MFAを明示的にスキップします。ID/パスワードでログインした場合はこのActionは何もしないため、前回設定した「常時MFAを要求する」ポリシーがそのまま有効になります。

  4. 右上の 「デプロイ」 をクリックして保存します。
    デプロイ

  5. Auth0ダッシュボードの左メニューから 「アクション」→「トリガー」→「サインアップとログイン」→「post-login」 を選択します。
    トリガー選択

  6. 作成したActionをフロー図の 開始 と 完了 の間の位置にドラッグ&ドロップして追加し、「適用」 をクリックします。
    フロー設定

これでログインの度に、このActionが実行されるようになりました。


3. 実際に動かしてみる

前回までに作成したReactアプリをそのまま起動します。

npm run dev

パターンA: Passkeyでログイン(MFAスキップを確認)

  1. http://localhost:5173 にアクセスし、 「Log In」 をクリックします。
    login

  2. Passkey登録済みのアカウントで、デバイスの生体認証(Touch ID / Windows Helloなど)でログインします。
    passkey-login

  3. MFAの入力画面は表示されず、そのままアプリ画面(ユーザー情報と「Log Out」ボタン)に遷移することを確認します。
    logout

パターンB: ID/パスワードでログイン(MFA要求を確認)

  1. 一度ログアウトし、再度 「Log In」 をクリックします。
    login

  2. 今度はメールアドレス/パスワードを入力してログインします(Passkeyのプロンプトが出た場合はスキップ、またはPasskey未登録の別アカウントを使用します)。
    ID/PW

  3. 前回同様、 TOTPアプリのコード入力画面が表示される ことを確認します。コードを入力してログインを完了します。
    mfa

同じアプリ・同じテナントでありながら、ログイン方法によってMFAの要求が自動的に出し分けられていることが確認できました。Reactアプリ側のコードは一切変更していません。


4. (応用編)APIのスコープに応じてMFAを要求する

今回は「ログイン方法」を条件にMFAを出し分けましたが、Actionsの event オブジェクトからは他にも様々なコンテキスト情報を参照できます。例えば、認可リクエストで要求されたスコープ(event.transaction.requested_scopes)を見て、機密性の高い操作に対応するスコープが要求された場合だけMFAを要求する、という組み方も可能です。

この例は、テナントのMFAポリシーが 「検証しない」 であることが前提です。前回設定した 「常時」 のままだと、すべてのログインでMFAが要求されるため、スコープによる絞り込みになりません。試す場合は、「セキュリティ」→「多要素認証」→「ポリシーを定義する」 でポリシーを「検証しない」に変更してください。なお、MFAが未登録のユーザーには、この例でもMFAの登録画面が表示されます。

exports.onExecutePostLogin = async (event, api) => {
  const CLIENTS_WITH_MFA = ['REPLACE_WITH_{yourClientId}'];

  if (CLIENTS_WITH_MFA.includes(event.client.client_id)) {
    if (event.transaction.requested_scopes.indexOf('transfer:funds') > -1) {
      api.multifactor.enable('any', { allowRememberBrowser: true });
    }
  }
};

これは「transfer:funds(送金)のスコープを要求しているクライアントからのログインにだけMFAを要求する」という例で、Auth0公式のステップアップ認証ドキュメントでも紹介されているパターンです。ログイン方法だけでなく、「どのAPI・どのスコープにアクセスしようとしているか」という情報もMFAの出し分けの条件に使えることがわかります。


まとめ

Auth0 Actionsを使って、ログイン方法に応じてMFAの要求を動的に出し分けてみました。

  • event.authentication.methods から、ログインに使われた認証方法(Passkey / ID/パスワードなど)を判定できる
  • api.multifactor.enable("none") を呼べば、特定の条件下でMFAをスキップできる
  • 逆に api.multifactor.enable("any", ...) のように呼べば、特定の条件下でMFAを追加で要求することもできる
  • 条件には認証方法だけでなく、event.transaction.requested_scopes(要求されたスコープ)なども使える
  • これらはダッシュボードの「ActionsでMFA要素をカスタマイズする」を有効化した上で、Reactアプリ側のコードを変更せずに実現できる

Passkeyのようなフィッシング耐性の高い認証方式を「もう一つの要素」とみなしてMFAをスキップする一方、相対的に弱いID/パスワード認証や、機密性の高い操作にはMFAを要求する。Actionsを使うことで、セキュリティとユーザー体験のバランスを、ユースケースに応じて柔軟に調整できることが確認できました。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?