Azure AD B2C IFrame内嵌登录后父页面无法获取ID Token问题咨询
解决方案
1. 修复IFrame跳转、父页面接收Token问题
你看到的ID Token是B2C返回到重定向URL的hash参数里的,因为重定向动作发生在IFrame内部,所以父页面默认无法直接获取。你需要给重定向URL对应的页面做专门的逻辑处理:
- 重定向页面不需要任何业务UI,只写token提取和跨帧通信的JS逻辑,示例代码如下:
// 重定向落地页JS代码 if(window.location.hash.includes('id_token')){ // 提取hash段内的所有凭证参数 const hashParams = new URLSearchParams(window.location.hash.slice(1)); const tokens = { idToken: hashParams.get('id_token'), accessToken: hashParams.get('access_token'), expiresIn: Number(hashParams.get('expires_in')) } // 父页面和重定向页同域时直接调用父页面暴露的接收方法 if(window.parent?.receiveB2CTokens){ window.parent.receiveB2CTokens(tokens); // 通信完成后隐藏/移除登录IFrame,避免展示落地页内容 const loginIframe = window.parent.document.getElementById('你的登录IFrame元素ID'); loginIframe.style.display = 'none'; loginIframe.remove(); } }
- 父页面提前暴露token接收方法,用于接收IFrame传递的凭证:
// 父页面全局JS代码,需要在IFrame加载前完成定义 window.receiveB2CTokens = function(tokens){ // 存储token到本地存储实现全应用共享 localStorage.setItem('b2c_id_token', tokens.idToken); if(tokens.accessToken){ localStorage.setItem('b2c_access_token', tokens.accessToken); localStorage.setItem('b2c_token_expire_at', Date.now() + tokens.expiresIn * 1000); } // 此处可补充登录成功后的业务逻辑,比如刷新用户状态、跳转业务页等 }
2. 配置获取Access Token
要同时获取ID Token和Access Token,你需要修改IFrame指向的B2C授权请求参数:
- 将
response_type参数值修改为id_token+token - 补充
scope参数,值需要包含openid profile以及你要访问的业务API对应的自定义scope,才能触发Access Token的返回 - 同时需要在Azure后台的B2C应用注册配置中,开启隐式授权流的「访问令牌」、「ID令牌」开关,否则授权请求会报错
3. 全应用范围内使用Token
你将Token存储到localStorage后,全应用都可以直接读取使用:
- 调用需要鉴权的业务API时,在请求头中添加
Authorization: Bearer ${localStorage.getItem('b2c_access_token')}即可 - 每次发起请求前可以判断Token有效期:如果当前时间大于
localStorage.getItem('b2c_token_expire_at')的值,可以通过隐藏IFrame发起静默授权请求刷新Token,无需用户重新登录
注意事项
需要确认你的B2C自定义策略中已经配置了允许IFrame嵌入的CSP规则,将父页面域名加入frame-ancestors白名单,避免IFrame加载被浏览器拦截。
内容的提问来源于stack exchange,提问作者Maximilian Anzinger
相关产品推荐
相关产品推荐

