mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-05-15 17:57:42 +01:00
web.config change
This commit is contained in:
@@ -147,18 +147,20 @@ export async function acquireMsalTokenForAccount(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// For Mooncake, popups to login.partner.microsoftonline.cn are blocked by COOP headers
|
// For Mooncake, popups to login.partner.microsoftonline.cn are blocked by COOP headers.
|
||||||
// (ERR_BLOCKED_BY_RESPONSE). Use loginRedirect instead for interactive sign-in.
|
// Use loginRedirect when running standalone (not in an iframe) so the top-level page can
|
||||||
// Silent attempts (prompt: "none") are skipped on Mooncake for the same reason —
|
// navigate away and return. Inside a portal iframe, redirect is forbidden by MSAL
|
||||||
// ssoSilent already failed above, so there is nothing more to try silently.
|
// (redirect_in_iframe), so we fall back to loginPopup — MSAL v5's redirect bridge
|
||||||
|
// handles COOP via BroadcastChannel rather than window.opener, so the popup still works.
|
||||||
const isMooncake = configContext.AAD_ENDPOINT === Constants.AadEndpoints.Mooncake;
|
const isMooncake = configContext.AAD_ENDPOINT === Constants.AadEndpoints.Mooncake;
|
||||||
if (isMooncake) {
|
const isInIframe = window !== window.parent;
|
||||||
|
if (isMooncake && !isInIframe) {
|
||||||
if (silent) {
|
if (silent) {
|
||||||
// ssoSilent already failed; a prompt:none popup would also be blocked on Mooncake.
|
// ssoSilent already failed; a redirect cannot be used silently.
|
||||||
// Re-throw so the caller knows silent acquisition was not possible.
|
// Re-throw so the caller knows silent acquisition was not possible.
|
||||||
throw new Error("Silent login not possible on Mooncake; interactive sign-in required.");
|
throw new Error("Silent login not possible on Mooncake; interactive sign-in required.");
|
||||||
}
|
}
|
||||||
// Interactive: navigate the browser to the Mooncake AAD login page.
|
// Standalone (hosted explorer): navigate the page to the Mooncake AAD login URL.
|
||||||
// On return, handleRedirectPromise() in getMsalInstance() will cache the token.
|
// On return, handleRedirectPromise() in getMsalInstance() will cache the token.
|
||||||
await msalInstance.loginRedirect({ prompt: "login", ...loginRequest });
|
await msalInstance.loginRedirect({ prompt: "login", ...loginRequest });
|
||||||
// Browser has navigated away; this line is never reached.
|
// Browser has navigated away; this line is never reached.
|
||||||
@@ -211,12 +213,16 @@ export async function acquireTokenWithMsal(
|
|||||||
} catch (silentError) {
|
} catch (silentError) {
|
||||||
if (silentError instanceof msal.InteractionRequiredAuthError && silent === false) {
|
if (silentError instanceof msal.InteractionRequiredAuthError && silent === false) {
|
||||||
// Sovereign cloud environments (e.g., Azure China / Mooncake) block popups in some
|
// Sovereign cloud environments (e.g., Azure China / Mooncake) block popups in some
|
||||||
// browser configurations. Use redirect-based flow instead to ensure compatibility.
|
// browser configurations. Use redirect-based flow instead when running standalone.
|
||||||
// Detection is based on configContext.AAD_ENDPOINT (set from the portal's serverId message
|
// Detection is based on configContext.AAD_ENDPOINT (set from the portal's serverId message
|
||||||
// via updateAADEndpoints), NOT window.location.host — the latter is unreliable when running
|
// via updateAADEndpoints), NOT window.location.host — the latter is unreliable when running
|
||||||
// the explorer locally (localhost) embedded inside portal.azure.cn.
|
// the explorer locally (localhost) embedded inside portal.azure.cn.
|
||||||
|
// Inside a portal iframe, redirect is forbidden by MSAL (redirect_in_iframe error), so
|
||||||
|
// we fall back to acquireTokenPopup — MSAL v5's redirect bridge handles COOP via
|
||||||
|
// BroadcastChannel (not window.opener) so the popup works even from within an iframe.
|
||||||
const isMooncake = configContext.AAD_ENDPOINT === Constants.AadEndpoints.Mooncake;
|
const isMooncake = configContext.AAD_ENDPOINT === Constants.AadEndpoints.Mooncake;
|
||||||
if (isMooncake) {
|
const isInIframe = window !== window.parent;
|
||||||
|
if (isMooncake && !isInIframe) {
|
||||||
try {
|
try {
|
||||||
// acquireTokenRedirect navigates the browser away; execution does not continue
|
// acquireTokenRedirect navigates the browser away; execution does not continue
|
||||||
// past this await. On return, getMsalInstance()'s handleRedirectPromise() will
|
// past this await. On return, getMsalInstance()'s handleRedirectPromise() will
|
||||||
|
|||||||
+39
@@ -65,6 +65,45 @@
|
|||||||
</staticContent>
|
</staticContent>
|
||||||
</system.webServer>
|
</system.webServer>
|
||||||
</location>
|
</location>
|
||||||
|
<!--
|
||||||
|
MSAL v5 redirect bridge requirements (https://aka.ms/msal.js/redirect-bridge):
|
||||||
|
1. Must NOT be served with Cross-Origin-Opener-Policy headers. If COOP is present on
|
||||||
|
the bridge page, the browser performs a browsing context group swap that severs the
|
||||||
|
BroadcastChannel communication channel back to the main application, causing
|
||||||
|
ERR_BLOCKED_BY_RESPONSE when the popup navigates to the AAD login endpoint.
|
||||||
|
The <remove> tag strips any COOP header added by Azure infrastructure globally.
|
||||||
|
The explicit unsafe-none value ensures no COOP is present even after clearing.
|
||||||
|
2. Must be served with Cache-Control: no-store. The bridge page carries auth codes
|
||||||
|
and tokens in its URL — caching by a CDN or proxy would expose those credentials.
|
||||||
|
-->
|
||||||
|
<location path="redirectBridge.html">
|
||||||
|
<system.webServer>
|
||||||
|
<staticContent>
|
||||||
|
<clientCache cacheControlMode="DisableCache" />
|
||||||
|
</staticContent>
|
||||||
|
<httpProtocol>
|
||||||
|
<customHeaders>
|
||||||
|
<remove name="Cross-Origin-Opener-Policy" />
|
||||||
|
<add name="Cross-Origin-Opener-Policy" value="unsafe-none" />
|
||||||
|
<add name="Cache-Control" value="no-store" />
|
||||||
|
</customHeaders>
|
||||||
|
</httpProtocol>
|
||||||
|
</system.webServer>
|
||||||
|
</location>
|
||||||
|
<location path="mpac/redirectBridge.html">
|
||||||
|
<system.webServer>
|
||||||
|
<staticContent>
|
||||||
|
<clientCache cacheControlMode="DisableCache" />
|
||||||
|
</staticContent>
|
||||||
|
<httpProtocol>
|
||||||
|
<customHeaders>
|
||||||
|
<remove name="Cross-Origin-Opener-Policy" />
|
||||||
|
<add name="Cross-Origin-Opener-Policy" value="unsafe-none" />
|
||||||
|
<add name="Cache-Control" value="no-store" />
|
||||||
|
</customHeaders>
|
||||||
|
</httpProtocol>
|
||||||
|
</system.webServer>
|
||||||
|
</location>
|
||||||
<location path="mpac/explorer.html">
|
<location path="mpac/explorer.html">
|
||||||
<system.webServer>
|
<system.webServer>
|
||||||
<staticContent>
|
<staticContent>
|
||||||
|
|||||||
Reference in New Issue
Block a user