Angular双WebApp基于MSAL SSO:跨应用登出同步及登录状态校验
Angular + MSAL 跨应用自动登出的状态检测方案
针对同租户下两个基于Angular+MSAL的SSO应用,实现一个登出后另一个自动登出,可通过以下几种机制实现:
1. 结合浏览器Storage事件与MSAL账户监听
当一个应用执行登出操作时,MSAL会更新本地存储(localStorage)中的账户信息。另一个应用可以通过监听浏览器的storage事件,捕获存储变化并检查账户状态:
代码示例
import { Component, OnInit } from '@angular/core'; import { MsalService } from '@azure/msal-angular'; @Component({ selector: 'app-root', templateUrl: './app.component.html', }) export class AppComponent implements OnInit { constructor(private msalService: MsalService) {} ngOnInit(): void { // 监听本地存储变化 window.addEventListener('storage', (event) => { // 过滤MSAL账户相关的存储键 if (event.key?.startsWith('msal.') && event.key.includes('.accounts')) { this.verifyAccountStatus(); } }); // 监听MSAL原生的账户移除事件 this.msalService.instance.addEventCallback((event) => { if (event.eventType === 'msal:accountRemoved') { this.triggerAppLogout(); } }); } private verifyAccountStatus(): void { const activeAccount = this.msalService.instance.getActiveAccount(); if (!activeAccount) { this.triggerAppLogout(); } } private triggerAppLogout(): void { // 执行应用内登出逻辑:清除本地业务缓存、跳转登录页等 localStorage.removeItem('app-specific-state'); window.location.href = '/auth/login'; } }
2. 定时主动检查账户状态
设置定时任务,周期性检查MSAL的账户列表,若账户为空则触发登出逻辑:
代码示例
// 在AppComponent或路由守卫中添加 ngOnInit(): void { // 每30秒检查一次账户状态 setInterval(() => { const accounts = this.msalService.instance.getAllAccounts(); if (accounts.length === 0) { this.triggerAppLogout(); } }, 30000); }
3. 静默登录状态验证
利用MSAL的静默登录机制,定期验证用户会话有效性,失败则说明已登出:
代码示例
private async checkSilentLoginStatus(): Promise<void> { try { await this.msalService.silentSso(); } catch (error) { // 静默登录失败,说明会话已失效 this.triggerAppLogout(); } } // 在ngOnInit或定时器中调用 ngOnInit(): void { setInterval(() => this.checkSilentLoginStatus(), 60000); }
注意事项
- 确保两个应用的MSAL配置使用
localStorage作为缓存位置(默认配置),若使用sessionStorage则跨应用/标签页的状态同步会失效。配置示例:export const msalConfig = { auth: { /* 租户、客户端ID等配置 */ }, cache: { cacheLocation: 'localStorage', storeAuthStateInCookie: false } }; - 若两个应用属于不同域名,浏览器Storage事件无法跨域监听,此时需配合Azure AD的会话管理机制,或通过跨域postMessage实现应用间通信,需两个应用提前约定通信规则。
内容的提问来源于stack exchange,提问作者meiksner
相关产品推荐
相关产品推荐

