多独立域名React应用共用Azure AD配置如何实现单点登录?
跨独立域名Azure AD集成React应用的SSO实现方案
你当前的架构已经满足SSO的核心前提:三个应用共用同一Azure AD租户ID、同一应用注册ID,且统一从祖父级应用进入,不需要额外调整AD侧的应用注册配置,选以下任意一种方案即可实现一次登录全应用访问,不需要重复校验身份。
方案1:利用Azure AD原生会话静默续期(改造成本最低,优先选)
用户在祖父级应用完成AD登录后,Azure AD会在自身的认证服务域名下写入全局会话Cookie,这个Cookie不受你三个业务域名的同源策略限制,本身就是AD用来做跨应用SSO的基础,你根本不需要手动在三个业务域之间传原始token:
- 父、子应用的前端初始化MSAL(或者你自己写的OAuth2授权码流逻辑)时,默认不主动触发登录跳转,先调用静默登录方法:发起授权请求时携带
prompt=none参数,禁止AD弹出交互登录页。 - AD收到带
prompt=none的请求后,会检查自身域下是否存在对应用户、对应app id的有效会话,如果存在就直接返回授权码,父/子应用拿授权码正常换access_token、refresh_token即可,全程无页面跳转、无登录弹窗,用户完全无感知。 - 加个兜底逻辑:如果静默登录失败(比如用户直接输入父/子应用域名访问,没走祖父级入口,或者AD会话过期),直接重定向回祖父级应用的登录页,完全符合你「仅能从祖父级应用发起登录」的访问规则。
注意:提前在Azure AD的对应应用注册里,把三个应用的回调重定向URI全部加进白名单,不然静默授权会被AD拦截。
方案2:跳转时一次性加密传递token(适配严格入口管控场景)
如果你的安全规则要求所有身份态必须从祖父级应用签发,不允许父/子应用直接和AD做静默交互,可以用短期一次性令牌做跨域传递:
- 祖父级应用完成登录拿到AD颁发的全量token后,由祖父级服务端(绝对不要在前端做加密,避免密钥泄漏)用三个应用后端共同持有的对称密钥,生成一个有效期不超过10秒、标记为单次使用的加密传递令牌,令牌内仅加密存储必要的身份信息和原始token密文,同时在服务端存下这个令牌的生成记录,用于后续防重放校验。
- 从祖父级跳转到父/子应用时,把这个加密传递令牌拼在目标URL的查询参数上,示例跳转地址:
https://www.parentapp.com/auth/callback?sso_token=加密串 - 父/子应用前端检测到URL带
sso_token参数时,第一时间把参数传给自身服务端做校验:一是验签确认令牌是祖父级签发,二是检查是否在有效期内,三是查服务端记录确认这个令牌没被使用过,三个校验全过才解密拿到原始token返回给前端。 - 前端拿到token后立刻清除URL上的
sso_token参数,避免令牌残留在浏览器历史、访问日志里,后续本域的token刷新直接走标准OAuth2刷新流程即可,不需要再跳转祖父级。
注意:绝对不要把未加密的原始token直接拼在URL里传递,URL会被浏览器历史、服务器日志、链路中间件记录,泄漏风险极高。
避坑提醒
- 不要尝试用iframe嵌套祖父级页面读取localStorage的方式拿token,跨根域名场景下同源策略会直接拦截,且这种方式XSS泄漏风险极高。
- 不要把refresh_token存在前端localStorage里,不管用哪种方案,token刷新逻辑最好走各应用的后端代理,refresh_token存在带HttpOnly、Secure属性的Cookie里,降低XSS偷取风险。
- 传递用的临时令牌必须设置极短有效期+单次使用限制,就算令牌被意外截获,也无法被复用登录。
- 如果用官方的
@azure/msal-react库,本身已经内置了同app id下的跨域静默SSO能力,只需要在初始化配置里把三个业务域名加入受信任域列表即可,不需要自己从零实现静默授权逻辑。
内容的提问来源于stack exchange,提问作者Maulik Dave
相关产品推荐
相关产品推荐

