You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Outlook插件提取认证弹窗URL中ID Token遇跨域报错求解决方案

解决Outlook插件提取ID Token的跨域安全错误

问题原因

你遇到的Uncaught DOMException是浏览器同源策略导致的:当弹窗跳转到IDP的认证域后,你的Outlook插件页面(父窗口)和弹窗页面属于不同域名,浏览器禁止父窗口访问不同域弹窗的location.href属性,以此防止跨域数据泄露。

可行解决方案

改用同域回调页面 + postMessage的方式,绕开同源限制,具体步骤如下:

1. 配置IDP重定向地址

修改IDP的认证配置,将认证成功后的重定向地址设置为一个和你的Outlook插件完全同域的静态页面(比如callback.html),确保协议、域名、端口完全一致。

2. 修改父窗口(插件页面)代码

移除轮询弹窗URL的逻辑,改为监听来自回调页面的消息:

function determineAuthenticationMethodAndRedirect(data, tenantId) {
    if (data.IdentityProvider.Enabled) {
        console.log("Identity Provider authentication is enabled");
        // 构造认证URL,指定同域回调地址
        const baseAuthUrl = Office.context.roamingSettings.get("userInput") + "/Apps/Erp/Home/";
        const callbackUrl = encodeURIComponent(window.location.origin + "/callback.html");
        const authUrl = `${baseAuthUrl}?redirect_uri=${callbackUrl}&tenantId=${tenantId}`;
        openPopup(authUrl);
    } else if (data.TokenAuthentication.Enabled) {
        console.log("Token-based authentication is enabled");
        window.location.href = "ep-collab-login.js";
    } else if (data.BasicAuthentication.Enabled) {
        console.log("Basic authentication is enabled");
    } else {
        console.log("No supported authentication method is enabled");
    }
}

function openPopup(url) {
    const popupWidth = 600;
    const popupHeight = 400;
    const popupSettings = `width=${popupWidth},height=${popupHeight},top=${(window.innerHeight - popupHeight)/2},left=${(window.innerWidth - popupWidth)/2},scrollbars=yes,resizable=yes`;
    const popup = window.open(url, "_blank", popupSettings);

    // 监听回调页面发送的消息
    window.addEventListener("message", (event) => {
        // 验证消息来源,避免恶意消息
        if (event.origin !== window.location.origin) return;

        if (event.data.type === "ID_TOKEN_RECEIVED") {
            const idToken = event.data.token;
            if (idToken) {
                console.log('ID Token:', idToken);
                // 这里可以加入后续API调用逻辑
            } else {
                console.log('ID Token not available');
            }
            popup.close();
        }
    });
}

3. 创建同域回调页面(callback.html)

这个页面负责提取URL中的ID Token,并通过postMessage发送给父窗口:

<!DOCTYPE html>
<html>
<head>
    <script>
        function extractIdTokenFromUrl(url) {
            const match = url.match(/[?&]id-token=([^&]*)/);
            return match ? decodeURIComponent(match[1]) : null;
        }

        window.onload = () => {
            const idToken = extractIdTokenFromUrl(window.location.href);
            // 向父窗口发送Token
            window.opener.postMessage(
                { type: "ID_TOKEN_RECEIVED", token: idToken },
                window.opener.location.origin
            );
            // 自动关闭页面
            setTimeout(() => window.close(), 500);
        };
    </script>
</head>
<body>
    <p>认证处理中,请稍候...</p>
</body>
</html>

关键注意事项

  • 回调页面必须和插件页面完全同源,否则postMessage会被浏览器拦截
  • 务必在IDP的允许重定向列表中添加这个回调页面地址,否则IDP会拒绝跳转
  • 不要尝试直接访问跨域弹窗的location属性,这是浏览器安全策略明确禁止的行为

内容的提问来源于stack exchange,提问作者Pearl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:22:36