如何使用@msal-react与Azure AD实现10分钟后触发会话过期弹窗
解决方案
你需要分别调整Azure AD端配置和客户端代码,即可实现10-15分钟会话到期后触发重新登录弹窗的需求,具体操作如下:
Azure AD端配置
- 配置自定义令牌生命周期:进入Azure门户→Azure Active Directory→应用注册→找到你的目标应用,可通过图形API或PowerShell为应用绑定令牌生命周期策略,将ID令牌、访问令牌的有效期设置为你需要的10或15分钟,最短支持10分钟的有效期配置。
- 配置登录频率策略:进入Azure AD→条件访问→新建策略,在「会话控制」模块中设置「登录频率」为10或15分钟,绑定到你的应用和目标用户群体,该策略会强制用户在指定时间后必须重新进行身份验证,无法通过刷新令牌无感续期。
- 调整刷新令牌配置(可选):你可以在应用注册的「身份验证」页面,将刷新令牌的有效期设置为和访问令牌一致,避免长效刷新令牌存在导致的会话续期风险。
客户端代码调整
你目前的逻辑是静默刷新失败后跳转登录,需要修改为会话到期后直接触发弹窗登录,参考修改后的代码如下:
import { EventType } from "@azure/msal-browser"; // 全局存储上次成功认证的时间戳 let lastAuthTime = Date.now(); const SESSION_MAX_DURATION = 15 * 60 * 1000; // 自定义会话时长,此处为15分钟 // 监听MSAL认证成功事件,更新认证时间 msalInstance.addEventCallback(event => { if (event.eventType === EventType.LOGIN_SUCCESS || event.eventType === EventType.ACQUIRE_TOKEN_SUCCESS) { lastAuthTime = Date.now(); } }); export const refreshIdToken = async (msalInstance: IPublicClientApplication) => { const account = msalInstance.getActiveAccount(); // 优先判断会话是否已超过最大时长 if (Date.now() - lastAuthTime > SESSION_MAX_DURATION) { // 会话到期直接触发弹窗登录 return msalInstance.acquireTokenPopup(loginRequest); } try { if (account != null) { const token = await msalInstance.acquireTokenSilent({ scopes: loginRequest.scopes, account }); return token.idToken; } } catch (error) { if (error instanceof InteractionRequiredAuthError) { // 静默刷新失败也触发弹窗登录,替换原有的跳转逻辑 return msalInstance.acquireTokenPopup(loginRequest); } else { console.error(error); } } }; const token = await refreshIdToken(msalInstance); axios.defaults.headers.common["Authorization"] = `Bearer ${token}`; // 后续API调用逻辑不变
如果不做客户端计时逻辑,仅配置Azure AD侧的登录频率策略,静默刷新时会直接抛出InteractionRequiredAuthError,你只需要将原代码中的acquireTokenRedirect替换为acquireTokenPopup即可触发弹窗登录。
内容的提问来源于stack exchange,提问作者Deepak Kothari
相关产品推荐
相关产品推荐

