注销
MSAL 的注销过程需要执行两个步骤。
- 清除 MSAL 缓存。
- 清除身份服务器上的会话。
该 PublicClientApplication 对象公开两个执行这些操作的 API。
msalInstance.logoutRedirect();
msalInstance.logoutPopup();
这些 API 将清除任何用户和会话数据的令牌缓存,然后将浏览器窗口或弹出窗口导航到服务器的注销页。 然后,服务器将提示用户选择要注销的帐户,并重定向回你的 postLogoutRedirectUri 帐户,前提是满足以下条件:
- 该 URI 已在应用注册中注册为回复 URL
- URI 作为
postLogoutRedirectUri在PublicClientApplication配置或注销请求中提供 - 用户与身份提供方之间存在有效会话
- (MSA 场景)在应用注册中配置了前端通道注销 URL
如果上述任一条件未满足,页面(或弹出窗口)将保留在标识提供者的注销页面上。
重要: 如果此注销导航以任何方式中断,可能会清除 MSAL 缓存,但会话仍可能保留在服务器上。 在返回到应用程序之前,请确保导航完全完成。
const msalConfig = {
auth: {
clientId: 'your_client_id',
authority: 'https://login.microsoftonline.con/{your_tenant_id}',
redirectUri: 'https://contoso.com',
postLogoutRedirectUri: 'https://contoso.com/homepage'
}
};
请求对象
可以将配置选项提供给每个注销 API,以自定义行为:
logoutRedirect
使用 logoutRedirect 将清除用户令牌的本地缓存,然后将窗口重定向到服务器注销页。
logoutRedirect 返回的 Promise 预计不会解析,但如果需要在重定向启动前阻止其他代码运行,你可以等待它。
可通过提供配置选项来自定义其行为:
const currentAccount = msalInstance.getAccount({ homeAccountId });
await msalInstance.logoutRedirect({
account: currentAccount,
postLogoutRedirectUri: "https://contoso.com/loggedOut"
});
跳过服务器注销
Warning
跳过服务器注销意味着用户的会话将在服务器上保持活动状态,并且可以重新登录到应用程序,而无需再次提供凭据。
如果您希望应用程序仅执行本地注销,可以为请求中的 onRedirectNavigate 参数提供一个回调函数,并使该回调返回 false。
msalInstance.logoutRedirect({
onRedirectNavigate: (url) => {
// Return false if you would like to stop navigation after local logout
return false;
}
});
logoutPopup
API logoutPopup 将在弹出窗口中打开服务器注销页,使应用程序能够保持其当前状态。 因此,在选择使用弹出窗口注销时,与 logoutRedirect 相比有一些额外的注意事项:
-
logoutPopup返回的 Promise 预计在弹出窗口关闭后解析 -
postLogoutRedirectUri是 MSAL 在注销完成后能够关闭弹出窗口所必需的 -
postLogoutRedirectUri将在弹出窗口中打开,而不是主框架。 如果需要在注销后重定向顶级应用,可以在mainWindowRedirectUri注销请求上使用参数。
可提供配置选项以自定义其行为。
const currentAccount = msalInstance.getAccount({ homeAccountId });
await msalInstance.logoutPopup({
account: currentAccount,
postLogoutRedirectUri: "https://contoso.com/loggedOut",
mainWindowRedirectUri: "https://contoso.com/homePage",
popupWindowAttributes: {
popupSize: {
height: 100,
width: 100
},
popupPosition: {
top: 100,
left: 100
}
}
});
无提示注销
如果客户端应用为 ID 令牌启用了 login_hint 可选声明,则可以利用 ID 令牌的 login_hint 声明,在使用 logoutRedirect 或 logoutPopup 时执行“静默”或无提示注销。 有两种方法可以实现无提示的注销:
选项 1:让 MSAL 自动从帐户的 ID 令牌声明中解析 login_hint
第一种也是最简单的方法,是将要结束其会话的账户对象提供给注销 API。 MSAL 将检查帐户的 ID 令牌中是否包含 login_hint 声明,并自动将其作为 logout_hint 添加到结束会话请求中,以跳过帐户选取器提示。
const currentAccount = msalInstance.getAccount({ homeAccountId });
// The account's ID Token must contain the login_hint optional claim to avoid the account picker
await msalInstance.logoutRedirect({ account: currentAccount});
选项 2:在注销请求中手动设置 logoutHint 选项
或者,如果你更愿意手动设置 logoutHint,则可以在应用中提取 login_hint 声明,并将其设置为注销请求中的 logoutHint:
const currentAccount = msalInstance.getAccount({ homeAccountId });
// Extract login hint to use as logout hint
const logoutHint = currentAccount.idTokenClaims.login_hint;
await msalInstance.logoutPopup({ logoutHint: logoutHint });
注意:根据你选择的 API(重定向/弹出窗口),应用仍将重定向或打开弹出窗口以终止服务器会话。区别在于用户不会看到或必须与服务器的帐户选取器提示进行交互。
前端通道注销
Microsoft Entra ID和Azure AD B2C 支持 OAuth 前端通道注销功能,该功能可在用户启动注销时跨所有应用程序进行单一注销。 若要通过 MSAL.js利用此功能,请执行以下步骤:
- 在应用程序中,创建专用注销页。 此页面 不应 执行任何其他功能,例如在页面加载时获取令牌(有关详细信息,请参阅下文)。 请注意,此页面将在隐藏的 iframe 中加载,并且对于 Microsoft Entra ID 和 MSA 用户,将包含
iss和sid查询参数。 - 在 Microsoft Entra 管理中心,导航到应用程序的“身份验证”页,并在“前端通道注销 URL”下注册步骤 1 中的页面。 请注意,此页面必须通过
https加载。
前端通道注销页面的要求
应生成用于前端通道注销的页面,如下所示:
- 在页面加载时,自动调用 MSAL
logoutRedirectAPI。 - 在
PublicClientApplication配置中,将system.allowRedirectInIframe设置为true。 - 调用
logout时,我们建议阻止 iframe 中的重定向到注销页面(请参阅 上图)。
Example:
const msal = new PublicClientApplication({
auth: {
clientId: "my-client-id"
},
system: {
allowRedirectInIframe: true
}
})
// Automatically on page load
msal.logoutRedirect({
onRedirectNavigate: () => {
// Return false to stop navigation after local logout
return false;
}
});
现在,当用户注销另一个应用程序时,应用程序的前端通道注销 URL 将加载到隐藏的 iframe 中,MSAL.js 将清除其缓存以完成单一注销。
注释
前通道注销并不总是受到各浏览器的支持。 Chromium 启用了 存储分区,Firefox 也支持 类似的标准,从而限制应用执行前通道注销。 有关本主题的官方 Entra 文档,请参阅 在不使用第三方 Cookie 的情况下对前端通道注销的限制。
前端通道注销示例
以下示例演示如何使用 MSAL.js实现前端通道注销:
- MSAL Angular v2: Angular 11 示例
- MSAL React: React 路由器示例
Events
如果应用的不同部分需要在无法直接访问由 logoutRedirect 或 logoutPopup 返回的 Promise 的情况下响应登出状态,可以使用 事件 API。
当注销成功或失败时,以及使用 logoutPopup 打开弹出窗口时,都会发出事件。
重要说明
- 如果未将帐户传递到注销 API,或者没有 EndSessionRequest 对象,它将注销所有帐户。
- 如果将帐户传递到注销 API,MSAL 将仅清除与该帐户相关的令牌。
- 服务器注销是一项便利功能,因此会尽力而为。 只要本地应用程序缓存已成功清除,注销 API 就会成功解析,无论服务器注销是否成功。
后续步骤
深入了解更高级的主题,例如: