Errors

BrowserConfigurationAuthErrors

スタブ化されたパブリック クライアント アプリケーションが呼び出されました

エラー メッセージ: パブリック クライアント アプリケーションのスタブ インスタンスが呼び出されました。 msal-react を使用する場合は、プロバイダーなしでコンテキストが使用されていないことを確認してください。

msal-react エラーを確認する

BrowserAuthErrors

インタラクション進行中

エラー メッセージ: 相互作用は現在進行中です。 対話型 API を呼び出す前に、この操作が完了していることを確認してください。

このエラーは、ある対話型 API (loginPopuploginRedirectacquireTokenPopupacquireTokenRedirect) が呼び出されたときに、別の対話型 API がまだ進行中だった場合に発生します。 login API と acquireToken API は非同期であるため、別の約束を呼び出す前に、結果として得られる約束が解決されていることを確認する必要があります。

loginPopupまたはacquireTokenPopup

これらの API から返された Promise が、別の API を呼び出す前に解決されていることを確認します。

❌次の例では、acquireTokenPopup が呼び出された時点では loginPopup がまだ進行中であるため、このエラーが発生します。

const request = { scopes: ["openid", "profile"] };
loginPopup();
acquireTokenPopup(request);

✔️ これを解決するには、別の API を呼び出す前にすべての対話型 API が解決されていることを確認する必要があります。

const request = { scopes: ["openid", "profile"] };
await msalInstance.loginPopup();
await msalInstance.acquireTokenPopup(request);

loginRedirectまたはacquireTokenRedirect

リダイレクト API を使用する場合は、リダイレクトから戻るときに handleRedirectPromise を呼び出す必要があります。 これにより、サーバーからのトークン応答が適切に処理され、一時キャッシュ エントリがクリーンアップされます。 このエラーは、アプリケーションがloginRedirectまたはacquireTokenRedirectを呼び出す前に、handleRedirectPromiseが完了する機会がない場合にスローされます。

❌次の例では、loginRedirectが 2 回目に呼び出された時点で、handleRedirectPromiseは以前のloginRedirect呼び出しからの応答をまだ処理しているため、このエラーがスローされます。

msalInstance.handleRedirectPromise();

const accounts = msalInstance.getAllAccounts();
if (accounts.length === 0) {
    // No user signed in
    msalInstance.loginRedirect();
}

✔️ 解決するには、対話型 API を呼び出す前に、 handleRedirectPromise が解決されるのを待つ必要があります。

await msalInstance.handleRedirectPromise();

const accounts = msalInstance.getAllAccounts();
if (accounts.length === 0) {
    // No user signed in
    msalInstance.loginRedirect();
}

または、次の方法を使用します。

msalInstance
    .handleRedirectPromise()
    .then((tokenResponse) => {
        if (!tokenResponse) {
            const accounts = msalInstance.getAllAccounts();
            if (accounts.length === 0) {
                // No user signed in
                msalInstance.loginRedirect();
            }
        } else {
            // Do something with the tokenResponse
        }
    })
    .catch((err) => {
        // Handle error
        console.error(err);
    });

メモ:loginRedirectではないページからacquireTokenRedirectまたはredirectUriを呼び出す場合は、handleRedirectPromise ページとリダイレクトを開始したページの両方でredirectUriが呼び出され、待機されていることを確認する必要があります。 これは、 redirectUri ページが最初に loginRedirect 呼び出したページへのリダイレクトを開始し、そのページがトークン応答を処理するためです。

ラッパーライブラリ

ラッパー ライブラリ (React または Angular) のいずれかを使用している場合は、このエラーが発生する可能性がある追加の理由から、これらの特定のライブラリのエラー ドキュメントを参照してください。

ラッパー ライブラリを使用していないが、アプリケーションが同時対話型要求をトリガーする可能性があることを懸念している場合は、トークン取得メソッドで対話を呼び出す前に、他の対話が進行中かどうかを確認する必要があります。 これを実現するには、 MSAL Events API を介して現在の MSAL 相互作用状態を出力するグローバル アプリケーション状態またはブロードキャスト サービスなどを実装します。

❌次の例では、acquireTokenPopup ブロック内のが、現時点で別の操作が行われているかどうかを確認しないため、このエラーがスローされます。

async function myAcquireToken(request) {
    const msalInstance = getMsalInstance(); // get the msal application instance

    const tokenRequest = {
        account: msalInstance.getActiveAccount() || null;
        ...request
    };

    let tokenResponse;

    try {
        // attempt silent acquisition first
        tokenResponse = await msalInstance.acquireTokenSilent(tokenRequest);
    } catch (error) {
        if (error instanceof InteractionRequiredAuthError) {
            try {
                tokenResponse = await msalInstance.acquireTokenPopup(tokenRequest);
            } catch (err) {
                console.log(err);
                // handle other errors
            }
        }

        console.log(error);
        // handle other errors
    }

    return tokenResponse;
};

const request = {
    scopes: ["User.Read"]
};

myAcquireToken(request);
myAcquireToken(request);

✔️ 解決するには、他の対話型 API を呼び出す前に、対話状態が None されるのを待つ必要があります。

async function myAcquireToken(request) {
    const msalInstance = getMsalInstance(); // get the msal application instance

    const tokenRequest = {
        account: msalInstance.getActiveAccount() || null;
        ...request
    };

    let tokenResponse;

    try {
        // attempt silent acquisition first
        tokenResponse = await msalInstance.acquireTokenSilent(tokenRequest);
    } catch (error) {
        if (error instanceof InteractionRequiredAuthError) {
            // check for any interactions
            if (myGlobalState.getInteractionStatus() !== InteractionStatus.None) {
                // throw a new error to be handled in the caller below
                throw new Error("interaction_in_progress");
            } else {
                // no interaction, invoke popup flow
                tokenResponse = await msalInstance.acquireTokenPopup(tokenRequest);
            }
        }

        console.log(error);
        // handle other errors
    }

    return tokenResponse;
};

async function myInteractionInProgressHandler() {
    /**
     * "myWaitFor" method polls the interaction status via getInteractionStatus() from
     * the application state and resolves when it's equal to "None".
     */
    await myWaitFor(() => myGlobalState.getInteractionStatus() === InteractionStatus.None);

    // wait is over, call myAcquireToken again to re-try acquireTokenSilent
    return (await myAcquireToken(tokenRequest));
};

const request = {
    scopes: ["User.Read"]
};

myAcquireToken(request).catch((e) => myInteractionInProgressHandler());
myAcquireToken(request).catch((e) => myInteractionInProgressHandler());

トラブルシューティングの手順

  • 詳細ログを有効に し、イベントの順序をトレースします。 handleRedirectPromiseが呼び出され、loginまたは acquireToken API が呼び出される前に返されることを確認します。

このエラーが発生する原因がわからない場合は、issue を作成し、次の情報を共有する準備をしてください。

  • 詳細ログ
  • 問題の再現に使用できるサンプル アプリやコード スニペット
  • ページを更新します。 エラーは消えませんか?
  • 新しいタブでアプリケーションを開きます。エラーは消えませんか?

block_iframe_reload

エラー メッセージ: MSAL が認証応答を検出したため、iframe 内で要求がブロックされました。

このエラーは、ssoSilent または acquireTokenSilent を呼び出したときに、redirectUri として使用しているページが login または acquireToken 関数を呼び出そうとすると発生します。 これに対して推奨される軽減策は、サイレント API を呼び出すときに MSAL を実装しない空白のページに redirectUri を設定するためです。 また、非表示の iframe ではページをレンダリングする必要がないため、パフォーマンスを向上させるという利点もあります。

✔️ これは要求ごとに行うことができます。次に例を示します。

msalInstance.acquireTokenSilent({
    scopes: ["User.Read"],
    redirectUri: "http://localhost:3000/blank.html",
});

この新しい redirectUri をアプリ登録に登録する必要があります。

この目的で専用の redirectUri を使用しない場合は、代わりに、サイレント API によって使用される非表示の iframe 内でレンダリングされるときに、 redirectUri が MSAL API を呼び出そうとしないようにする必要があります。

monitor_window_timeout

エラー メッセージ:

  • タイムアウトのため、iframe でのトークンの取得に失敗しました。

このエラーは、ssoSilentacquireTokenSilentacquireTokenPopup、または loginPopup を呼び出したときに発生することがあり、その理由はいくつかあります。 最も一般的なものは次のとおりです。

  1. redirectUriとして使用するページは、ハッシュを削除または操作しています
  2. redirectUriとして使用するページは、自動的に別のページに移動します。
  3. ID プロバイダーにより制限されています
  4. ID プロバイダーがredirectUriにリダイレクトしませんでした。

重要: アプリケーションでルーター ライブラリ (React Router、Angular Router など) を使用している場合は、MSAL トークンの取得の進行中にハッシュまたは自動リダイレクトが削除されないことを確認してください。 可能であれば、 redirectUri ページがルーターをまったく呼び出さない場合に最適です。

redirectUri ページによって発生する問題

サイレント呼び出しを行うと、場合によっては iframe が開き、ID プロバイダーの承認ページに移動します。 ID プロバイダーがユーザーを承認すると、ハッシュ フラグメント内の承認コードまたはエラー情報を使用して iframe が redirectUri にリダイレクトされます。 最初に要求を行ったフレームまたはウィンドウで実行されている MSAL インスタンスは、この応答ハッシュを抽出して処理します。 redirectUri がこのハッシュを削除または操作している場合、または MSAL がこのハッシュを抽出する前に別のページに移動した場合、このタイムアウト エラーが発生します。

✔️ この問題を解決するには、 redirectUri として使用するページが、少なくともポップアップまたは iframe に読み込まれるときに、これらの処理を実行しないようにする必要があります。 これらの処理が発生しないように、サイレント フローとポップアップ フローの redirectUri として空白のページを使用することをお勧めします。

これは要求ごとに行うことができます。次に例を示します。

msalInstance.acquireTokenSilent({
    scopes: ["User.Read"],
    redirectUri: "http://localhost:3000/blank.html",
});

この新しい redirectUri をアプリ登録に登録する必要があります。

Angular と React に関する注意事項:

  • @azure/msal-angularを使用している場合は、redirectUri ページをMsalGuardで保護しないでください。
  • @azure/msal-react を使用している場合、redirectUri ページでは MsalAuthenticationComponent をレンダリングせず、useMsalAuthentication フックも使用しないでください。

ID プロバイダーによって発生する問題

Throttling

このエラーがスローされる最も一般的な理由の 1 つは、アプリケーションがループでスタックしたり、短時間でトークン要求が多すぎたりしたことです。 この場合、ID プロバイダーは短時間、後続のリクエストを制限することがあり、その結果、redirectUri にリダイレクトされなくなり、最終的にこのエラーが発生します。

✔️ スロットリングに起因する問題を解決するには、次の 2 つの方法があります。

  1. 再試行する前に、しばらくの間要求を停止してください。
  2. acquireTokenPopupacquireTokenRedirectなどの対話型 API を呼び出します。
X-Frame-Options 拒否

ID プロバイダーがアプリケーションへのリダイレクトに失敗した場合も、このエラーが発生する可能性があります。 サイレント シナリオでは、このエラーに X-Frame-Options: Deny エラーが伴うことがあります。これは、ID プロバイダーがエラー メッセージを表示しようとしているか、またはユーザーの操作を必要としていることを示しています。

✔️ X-Frame-Options エラーには通常、URL が含まれており、この URL を新しいタブで開くと、何が起こっているかを識別するのに役立つ場合があります。 対話が必要な場合は、代わりに対話型 API を使用することを検討してください。 エラーが表示されている場合は、エラーに対処します。

一部の B2C フローでは、ユーザーの操作を必要とするため、このエラーが発生することが想定されます。 これらのフローは次のとおりです。

  • パスワードのリセット
  • プロファイルの編集
  • サインアップ
  • 構成方法に応じた一部のカスタム ポリシー
ネットワーク待機時間

ID プロバイダーが時間内にアプリケーションにリダイレクトしないもう 1 つの考えられる理由は、ネットワーク待機時間が増える可能性があります。

✔️ 既定のタイムアウトは約 10 秒であり、ほとんどの場合は十分ですが、ID プロバイダーがリダイレクトに時間がかかっている場合は、 iframeHashTimeoutwindowHashTimeout 、または loadFrameTimeout 構成パラメーターを使用して MSAL 構成でこのタイムアウトを増やすことができます。

const msalConfig = {
    auth: {
        clientId: "your-client-id",
    },
    system: {
        windowHashTimeout: 9000, // Applies just to popup calls - In milliseconds
        iframeHashTimeout: 9000, // Applies just to silent calls - In milliseconds
        loadFrameTimeout: 9000, // Applies to both silent and popup calls - In milliseconds
    },
};

hash_empty_error

エラー メッセージ:

ハッシュ値は空であるため、処理できません。 redirectUri でハッシュがクリアされていないことを確認してください。

このエラーは、redirectUri として使用するページがハッシュを削除している場合、または別のページに自動リダイレクトしているときに発生します。 これは最も一般的に、アプリケーションが別のルートに移動し、ハッシュをドロップするルーターを実装する場合に発生します。

このエラーを解決するには、ルーターの対象ではない専用の redirectUri ページを使用することをお勧めします。 サイレント呼び出しとポップアップ呼び出しの場合は、空白のページを使用することをお勧めします。 これが不可能な場合は、MSAL トークンの取得の進行中にルーターが移動しないことを確認してください。 これを行うには、アプリケーションがサイレント呼び出しでは iframe 内に、ポップアップ呼び出しではポップアップ内に読み込まれているかどうかを検出するか、リダイレクト呼び出しでは handleRedirectPromise を待つことで実行できます。

ハッシュに既知のプロパティが含まれていません

エラー メッセージ:

ハッシュに既知の固有値が含まれていません。 redirectUri でハッシュが変更されていないことを確認してください。

上記の hash_empty_error については、説明を参照してください。 このエラーの根本原因は似ていますが、ハッシュが削除されるのではなく変更されています。

ネイティブ プラットフォームからトークンを取得できません

エラー メッセージ:

  • ネイティブ プラットフォームからトークンを取得できません。

このエラーは、acquireTokenByCodeではなくnativeAccountIdを使用して code API を呼び出し、ネイティブ ブローカーからトークンを取得しない環境でアプリが実行されている場合にスローされます。 前提条件の一覧については、 デバイス バインド トークンに関するドキュメントを参照してください。

ネイティブ接続が確立されていません

エラー メッセージ:

  • ネイティブ プラットフォームへの接続が確立されていません。 互換性のあるブラウザー拡張機能をインストールし、initialize() を実行してください。

このエラーは、ユーザーがネイティブブローカーでサインインしているものの、ネイティブブローカーへの接続が現在確立されていない場合に発生します。 これが発生する理由としては次のようなことが考えられます。

  • Windows アカウント拡張機能がアンインストールまたは無効になりました
  • initializeAPI が呼び出されていないか、別の MSAL API を呼び出す前に待機されていません

未初期化のパブリック クライアント アプリケーション

エラー メッセージ:

  • 他の MSAL API を呼び出す前に、initialize 関数を呼び出して待機する必要があります。

このエラーは、login API が呼び出される前に、acquireTokenhandleRedirectPromise、またはinitialize API が呼び出されたときにスローされます。 トークンの取得を試みる前に、 initialize API を呼び出して待機する必要があります。

❌次の例では、初期化が完了する前に handleRedirectPromise が呼び出されるため、このエラーがスローされます。

const msalInstance = new PublicClientApplication({
    auth: {
        clientId: "your-client-id",
    },
    system: {
        allowNativeBroker: true,
    },
});

await msalInstance.handleRedirectPromise(); // This will throw
msalInstance.acquireTokenSilent(); // This will also throw

✔️ 解決するには、他の MSAL API を呼び出す前に、 initialize が解決されるまで待つ必要があります。

const msalInstance = new PublicClientApplication({
    auth: {
        clientId: "your-client-id",
    },
    system: {
        allowNativeBroker: true,
    },
});

await msalInstance.initialize();
await msalInstance.handleRedirectPromise(); // This will no longer throw this error since initialize completed before this was invoked
msalInstance.acquireTokenSilent(); // This will also no longer throw this error

Other

msal でスローされないエラー (サーバー エラーなど)

[url] へのアクセスは、CORS ポリシーによってブロックされました

このエラーは、MSAL.js v2.x で発生し、Azure portalでのアプリの登録中に不適切な構成が原因で発生します。 特に、App Registration の Authentication ブレードで、redirectUri が種類: Single-page application として登録されていることを確認してください。 正常に完了すると、次の緑色のチェックマークが表示されます。

リダイレクト URI は、PKCE を使用した承認コード フローの対象となります。

画像