> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> ID Token を確認して、ユーザーが多要素認証（MFA）でウェブアプリにログインしたかどうかを判別する方法を学びます。

# Webアプリのステップアップ認証を設定する

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

ステップアップ認証では、さまざまな種類のリソースへのアクセスを許可するアプリケーションで、機密情報へのアクセスや特定のトランザクションの実行時に、より強固な認証方式をユーザーに要求できます。

たとえば、ユーザーは <Tooltip tip="多要素認証（MFA）: SMS で送信されるコードなど、ユーザー名とパスワードに加えて別の要素を使用するユーザー認証プロセス。" cta="用語集を表示" href="/docs/ja-jp/glossary?term=multi-factor+authentication">多要素認証</Tooltip> (MFA) で本人確認を済ませた場合にのみ、機密データを含む画面へのアクセスやパスワードのリセットを許可されることがあります。

Web アプリでステップアップ認証を実現するには、Web アプリから要求があったときに MFA での認証をユーザーに求める Action を作成します。さらに、ユーザーが制限されたページにアクセスしようとした際に、MFA に関する <Tooltip tip="ID Token: リソースへのアクセスではなく、クライアント自体を対象とした資格情報。" cta="用語集を表示" href="/docs/ja-jp/glossary?term=ID+Token">ID Token</Tooltip> のクレームを確認し、クレームに MFA が含まれていなければユーザーに認証を求めます。

<div id="validate-id-tokens-for-mfa">
  ## MFA 向けに ID トークンを検証する
</div>

ユーザーがログインすると、ユーザーのセッションに関連する情報をクレームとして含む [ID トークン](/docs/ja-jp/secure/tokens/id-tokens/get-id-tokens) を受け取ります。該当するクレームは `amr` (authentication methods reference) で、ログイン時に使用された認証方法を示す文字列の JSON 配列です。これは ID トークンのペイロードに含まれている必要があり、値 `mfa` を含んでいなければなりません。

その値には、あらかじめ定義された [Authentication Method Reference Values](https://tools.ietf.org/html/rfc8176) のいずれかが含まれる場合があります。`mfa` 以外の値も含まれる可能性があるため、検証時には `amr` が存在することを確認し、その内容に `mfa` が含まれているかどうかも確認する必要があります。

ユーザーが制限されたページにアクセスしようとした際に、トークンからそのユーザーが MFA で認証されていないことがわかった場合は、認証を再度トリガーできます。これにより、Action を使用して MFA が実行されるように構成した認証フローを再実行できます。ユーザーが第 2 要素を提示すると、`amr` クレームを含む新しい ID トークンが生成され、アプリに送信されます。

1. [ID トークンを取得する](/docs/ja-jp/secure/tokens/id-tokens/get-id-tokens)。
2. トークンの署名を検証します。これにより、トークンの送信者が名乗っている本人であることを確認し、メッセージが途中で改ざんされていないことを確かめられます。
3. 次のクレームを検証します。

| クレーム  | 説明                                                                                                                 |
| ----- | ------------------------------------------------------------------------------------------------------------------ |
| `exp` | トークンの有効期限                                                                                                          |
| `iss` | トークンの発行者                                                                                                           |
| `aud` | トークンの想定受信者                                                                                                         |
| `amr` | `amr` がペイロード内に存在しない、または値 `mfa` を含まない場合、ユーザーは MFA でログインしていません。`amr` がペイロード内に存在し、値 `mfa` を含む場合、ユーザーは MFA でログインしています。 |

<div id="amr-claim-exceptions">
  #### AMRクレームの例外
</div>

`amr` クレームは、次のユースケースを除いて必須です。

1. ホスト型ログインフローでは、ユーザーが MFA チャレンジを正常に完了した場合にのみ、`amr` クレームが IDトークンに追加されます。アプリが新たに発行された IDトークンに対してサイレント認証またはリフレッシュトークンを使用する場合、ユーザーは以前に MFA を使ってログインを完了しているため、`amr` クレームは含まれません。
2. MFA API で発行されたトークンには `amr` クレームは含まれません。`amr` クレームは、ユーザーが IDトークンを受け取る際に使用された認証方式を示します。MFA API の認証プロセスでは、アプリケーションが認証フローを制御し、必要に応じて MFA を要求できます。

以下の例では、ユーザーが MFA で認証した場合としていない場合で、IDトークンのペイロードに含まれる可能性のある値を比較できます。

<div id="example-values-with-mfa">
  ### 例: MFAありの場合の値
</div>

export const codeExample1 = `{
    "iss": "https://{yourDomain}/",
    "sub": "auth0|1a2b3c4d5e6f7g8h9i",
    "aud": "{yourClientId}",
    "iat": 1522838054,
    "exp": 1522874054,
    "acr": "http://schemas.openid.net/pape/policies/2007/06/multi-factor",
    "amr": [
        "mfa"
    ]
}`;

<AuthCodeBlock children={codeExample1} language="json" />

<div id="example-values-without-mfa">
  ### 例: MFAなしの値
</div>

export const codeExample2 = `{
    "iss": "https://{yourDomain}/",
    "sub": "auth0|1a2b3c4d5e6f7g8h9i",
    "aud": "{yourClientId}",
    "iat": 1522838054,
    "exp": 1522874054
}`;

<AuthCodeBlock children={codeExample2} language="json" />

<div id="scenario-salary-data-with-push-notifications">
  ## シナリオ: プッシュ通知による給与データへのアクセス
</div>

次のシナリオでは、Web アプリがユーザーをユーザー名とパスワードで認証します。給与データを表示する特定の画面にアクセスしたいユーザーは、Guardian のプッシュ認証要素で追加認証を行う必要があります。

<div id="prerequisites">
  ### 前提条件
</div>

このシナリオでは、Auth0 Dashboard で次の項目を設定する必要があります。

* [Web アプリを登録する](/docs/ja-jp/get-started/auth0-overview/create-applications/regular-web-apps)。
* [データベース接続を作成する](https://manage.auth0.com/#/connections/database)。
* プッシュ通知を使用するには、[MFA を有効にする](/docs/ja-jp/secure/multi-factor-authentication/enable-mfa)。

<div id="create-an-action">
  ### Action を作成する
</div>

ウェブアプリから要求されたときに、ユーザーに MFA での認証を求める Action を作成します。[Auth0 Dashboard > Actions > Flows](https://manage.auth0.com/#/actions/flows) に移動し、次の内容を含む Action を作成します。

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
 const CLIENTS_WITH_MFA = ['REPLACE_WITH_{yourClientId}'];
 // 指定されたクライアントのみ実行する
 if (CLIENTS_WITH_MFA.includes(event.client.client_id)) {
 // ウェブアプリが認証リクエストでMFAを要求した場合のみMFAを求める
 if (event.transaction?.acr_values.includes('http://schemas.openid.net/pape/policies/2007/06/multi-factor')) {
 api.multifactor.enable('any', { allowRememberBrowser: false });
 }
 }
}
```

* `CLIENTS_WITH_MFA` 変数には、この Action を適用するアプリケーションの<Tooltip tip="Client ID: Auth0 から登録済みリソースに付与される識別子です。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=client+IDs">client IDs</Tooltip>が含まれます。不要であれば、これ (および後続の `if` 条件) を削除できます。
* `event.transaction.acr_values` プロパティは、認証コンテキストクラス参照 (`acr`) を含む文字列の配列です。これは省略可能なプロパティで、アプリケーションが <Tooltip tip="Authorization Server: ユーザーのアクセス範囲を定義するうえで中心的な役割を果たすサーバーです。たとえば、Authorization Server は、ユーザーが利用できるデータ、タスク、機能を制御できます。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=Authorization+Server">Authorization Server</Tooltip> への認証リクエストにこれを含めた場合にのみ存在します。この例では、Web アプリは、まだ MFA で認証していないユーザーが給与情報にアクセスしようとした場合にのみ、これを認証リクエストに含めます。Web アプリがこれを含める場合、`http://schemas.openid.net/pape/policies/2007/06/multi-factor` という値を設定します。これは、Authorization Server に MFA を要求させたいことを示します。また、コードで設定した `api.multifactor` プロパティの値により、テナントで設定されている利用可能ないずれかの方法を使って、ユーザーに MFA チャレンジを求めます。`api.multifactor.enable()` メソッドの詳細については、[Action Triggers: post-login API object](/docs/ja-jp/customize/actions/explore-triggers/password-reset-triggers/post-challenge-trigger/post-challenge-api-object) を参照してください。
* `http://schemas.openid.net/pape/policies/2007/06/multi-factor` ポリシーは、エンドユーザーが複数の認証要素、つまり MFA を提示して <Tooltip tip="OpenID: アプリケーションがログイン情報を収集・保存することなくユーザーの本人確認を行えるようにする認証のオープン標準。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=OpenID">OpenID</Tooltip> Provider に認証する認証メカニズムを定義します。詳しくは、[OpenID Provider Authentication Policy Extension 1.0](https://openid.net/specs/openid-provider-authentication-policy-extension-1_0.html) を参照してください。

<div id="configure-app">
  ### アプリを設定する
</div>

ユーザーが制限された給与情報ページにアクセスしようとした際に、MFA を使用して認証済みであることを確認するようアプリを設定します。 (ユーザーが MFA で認証されている場合、ID トークンのクレームには、値が `mfa` の `amr` クレームが含まれます。) ユーザーがすでに MFA で認証されていれば、ウェブアプリは制限されたページを表示します。そうでない場合、ウェブアプリは、値が
`http://schemas.openid.net/pape/policies/2007/06/multi-factor`の `acr_values` パラメータを含む新しい認証リクエストを送信し、これによって Action がトリガーされます。

このシナリオのウェブアプリは認証に [Authorization Code Flow](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow) を使用するため、リクエストは次のとおりです。

export const codeExample3 = `https://{yourDomain}/authorize?
        audience=https://{yourDomain}/userinfo&
        scope=openid&
        response_type=code&
        client_id={yourClientId}&
        redirect_uri={https://yourApp/callback}&
        state={yourOpaqueValue}&
        acr_values=http://schemas.openid.net/pape/policies/2007/06/multi-factor`;

<AuthCodeBlock children={codeExample3} language="http" />

ユーザーがMFAで認証されると、WebアプリはAuthorization Codeを受け取ります。これを新しいIDトークンと交換する必要があります。新しいIDトークンには、`mfa` を値に持つ `amr` クレーム が含まれているはずです。コードをIDトークンに交換する方法については、[Authorization Code Flow を使用してログインを追加する](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow/add-login-auth-code-flow) を参照してください。

<div id="validate-id-token">
  ### ID トークンを検証する
</div>

このシナリオでは、[JSON Web Token Sample Code](https://github.com/auth0/node-jsonwebtoken) を使って検証します。具体的には、トークンの署名を検証し (`jwt.verify`) 、トークンをデコードして、ペイロード に `amr` が含まれているかどうかを確認し、含まれている場合は結果をコンソールに出力します。

export const codeExample4 = `const AUTH0_CLIENT_SECRET = '{yourClientSecret}';
const jwt = require('jsonwebtoken');

jwt.verify(id_token, AUTH0_CLIENT_SECRET, { algorithms: ['HS256'] }, function(err, decoded) {
  if (err) {
    console.log('無効なトークンです');
    return;
  }

  if (Array.isArray(decoded.amr) && decoded.amr.indexOf('mfa') >= 0) {
    console.log('MFA を使用しています');
    return;
  }

  console.log('MFA を使用していません');
});`;

<AuthCodeBlock children={codeExample4} language="javascript" />

<div id="learn-more">
  ## 詳しくはこちら
</div>

* [ID トークン](/docs/ja-jp/secure/tokens/id-tokens)
* [Rule のユースケース](/docs/ja-jp/customize/rules/use-cases)
* [JSON Web Token](/docs/ja-jp/secure/tokens/json-web-tokens)
* [API のステップアップ認証を設定する](/docs/ja-jp/secure/multi-factor-authentication/step-up-authentication/configure-step-up-authentication-for-apis)
