既定では、MSAL は、アプリが iframe 内にレンダリングされるときに、Microsoft Entra ID認証エンドポイントへのフルフレーム リダイレクトを防止します。つまり、IdP とのユーザー操作にリダイレクト API を使用することはできません。
-
この制限は、Microsoft Entra IDは、クリックジャッキング攻撃を防ぐための手段であるエラーをスローすることによって、ユーザーの操作 (
X-FRAME OPTIONS SET TO DENY、同意、ログアウトなど) を必要とするプロンプトを iframe に表示することを拒否するためです。 - 代わりに、ユーザー操作が必要な場合は MSAL の ポップアップ API に依存し、ユーザー操作を回避できる場合はサイレント API (
ssoSilent()、acquireTokenSilent()) に依存する必要があります。 - 同様に、サインアウトには logoutPopup() API を使用する必要があります (:warning: アプリで v2.13 より前のバージョンの
msal-browserを使用している場合は、logout()API をアップグレードして置き換えてください。Microsoft Entra IDへのフル フレーム リダイレクトが試行されるためです)。 -
ポップアップ API を使用する場合は、親アプリによって課されるサンドボックス制限を考慮する必要があります。 特に、親アプリは、iframe がサンドボックス化されるときに
allow-popupsフラグを設定する必要があります。
Azure AD B2C には、iframe でカスタム ログイン UI をレンダリングできる埋め込みサインイン エクスペリエンスが用意されています。 MSAL では既定で iframe でのリダイレクトが禁止されるため、この機能を利用するには allowRedirectInIframe 構成オプションを true に設定する必要があります。 上記の制限により、Microsoft Entra ID上のアプリでこのオプションを有効にすることはお勧めしません。
ブラウザーの制限
iframe 内のMicrosoft Entraセッション Cookie はサード パーティの Cookie と見なされるため、特定のブラウザー (シークレット モードのSafari や Chrome など) は、既定でこれらの Cookie をブロックまたはクリアします。 IdP のセッション Cookie にアクセスできないため、iframed アプリの シングル サインオン エクスペリエンスに影響します (「 シングル サインオン」を参照)。
さらに、 Chrome でサード パーティの Cookie が無効になっている場合、iframed MSAL アプリはローカルまたはセッション ストレージにアクセスできません。 この場合、MSAL はメモリ内ストレージにフォールバックします。
単一サインイン
親アプリから iframe に埋め込まれたアプリに アカウント ヒント を渡すと、同一オリジンおよびクロスオリジンの iframe に埋め込まれたアプリと親アプリの間で、シングル サインオンを実現できます。
同一オリジンのアプリ
同じ配信元の Iframed アプリと親アプリは、同じ MSAL.js キャッシュ インスタンスにアクセスでき、両方のアプリがキャッシュに ローカル ストレージ を使用するように MSAL を構成している場合、プロンプトなしでサインインできます。 詳細については、「MSAL.jsでのシングル サインオン」を参照してください。
クロスオリジンを使用するアプリ
クロスオリジンの Iframed アプリと親アプリでは、 ssoSilent() API を使用してシングル サインオンを実現できます。 これを行うには、親アプリが アカウント、 loginHint (ユーザー名) または セッション ID (sid) を iframed アプリに渡す必要があります。
アプリは、上記のパラメーターなしで ssoSilent の使用を試みることができます。 ただし、ユーザーのセッションに関する情報を提供せずにを使用する場合は、ssoSilentがあることに注意してください。
iframed アプリと親アプリの間のクロスオリジン通信には、いくつかの選択肢を検討できます。
- 親アプリで iframe のソースにクエリ文字列を追加し、後で子で取得できます。
// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication({
auth: {
clientId: "ENTER_CLIENT_ID",
authority: "https://login.microsoftonline.com/ENTER_TENANT_ID",
redirectUri: "/redirect", // set to a blank page for handling auth code response via popups
},
cache: {
cacheLocation: "localStorage", // set your cache location to local storage
},
});
window.onload = () => {
const urlParams = new URLSearchParams(window.location.search);
const sid = urlParams.get("sid");
// attempt SSO
myMSALObj.ssoSilent({
sid: sid
}).then((response) => {
// do something with response
}).catch(error => {
// handle errors
});
}
- 親アプリで postMessage() API を使用し、子アプリのメッセージ イベントをリッスンできます。
// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication({
auth: {
clientId: "ENTER_CLIENT_ID",
authority: "https://login.microsoftonline.com/ENTER_TENANT_ID",
redirectUri: "/redirect", // set to a blank page for handling auth code response via popups
},
cache: {
cacheLocation: "localStorage", // set your cache location to local storage
},
});
const parentDomain = "http://localhost:3001";
window.addEventListener("message", (event) => {
// check the origin of the data
if (event.origin === parentDomain) {
const sid = event.data;
// attempt SSO
myMSALObj.ssoSilent({
sid: sid
}).then((response) => {
// do something with response
}).catch(error => {
// handle errors
});
}
});
エラー処理
ssoSilent()が失敗した場合は、エラーをキャッチして処理する必要があります。 具体的には次のとおりです。
- InteractionRequiredError: 同意が必要な場合、ユーザーが MFA などを実行する必要がある場合にスローされます。このエラーは、多くの場合、対話型 API を開始するだけで処理できます。
-
BrowserAuthError: アカウント ヒント が指定されていない場合や無効な場合、ポップアップがブロックされている場合などにスローされます。
errorCodeを確認し、これらに適切に対処する必要があります。
myMSALObj.ssoSilent({
sid: sid
}).then((response) => {
// do something with response
}).catch(error => {
if (error instanceof msal.InteractionRequiredAuthError) {
myMSALObj.loginPopup()
.then((response) => {
// do something with response
});
} else if (error instanceof msal.BrowserAuthError) {
if (error.errorCode === "silent_sso_error") {
// e.g. username is null
}
if (error.errorCode === "popup_window_error") {
// e.g. popups are blocked
}
} else {
console.log(error);
}
});
ユーザー操作
ユーザーの操作を必要とする IdP との通信を最小限に抑える場合、または何らかの理由でポップアップに問題がある場合は、いくつかのオプションを検討できます。
管理者の同意を付与します。 これにより、ユーザーが初めてサインインするときに、アプリで必要なアクセス許可に対する同意プロンプトが表示されなくなります。
クライアント アプリを事前に承認します。 これにより、クライアント アプリによって呼び出されたときに、Web API に必要なアクセス許可に対する同意プロンプトが表示されなくなります。
シングル サインアウト
MSAL.js をフロント チャネル ログアウト URI と共に使用して、iframed アプリと親アプリの間でシングル サインアウト効果を実現できます。 たとえば、ユーザーが親アプリからログアウトするときに、ユーザーが iframed アプリから自動的にログアウトするようにする場合は、iframed アプリのフロント チャネル ログアウトを有効にする必要があります。 これを行うには、「 フロント チャネル ログアウト URI を構成する方法」を参照してください。