可以将 MSAL.js 库与嵌套应用身份验证配合使用,以便从 Office 外接程序使用单一登录 (SSO) 。 使用嵌套应用身份验证 (NAA) 比代表 (OBO) 流具有多个优势。
- 只需使用 MSAL.js 库,而不需要
getAccessTokenOffice.js 中的 函数。 - 可以使用来自客户端代码的访问令牌(作为 SPA)调用 Microsoft Graph 等服务。 无需使用中间层服务器。
- 可以对范围使用增量和动态许可。
- 无需 预授权主机 (例如 Teams、Office) 来调用终结点。
NAA 支持的帐户和主机
NAA 支持Microsoft帐户和Microsoft Entra ID (工作/学校) 标识。 它不支持适用于企业到消费者标识管理方案的 Azure Active Directory B2C 。 下表按平台说明了当前支持。 (正式发布) 列出的平台已准备好在外接程序中使用。
| 应用程序 | Web | Windows | Mac | iOS/iPad | Android |
|---|---|---|---|---|---|
| Excel | 预览版 | 预览版 | 预览版 | iPad 上的预览版 | 不适用 |
| Outlook | GA | GA | GA | ga (iOS) | GA |
| PowerPoint | 预览版 | 预览版 | 预览版 | iPad 上的预览版 | 不适用 |
| Word | 预览版 | 预览版 | 预览版 | iPad 上的预览版 | 不适用 |
重要
若要在仍处于预览 (Word、Excel 和 PowerPoint) 预览版的平台上使用 NAA,请加入 Microsoft 365 预览体验计划,然后选择“当前频道 (预览版”) 。 请勿在任何预览平台的生产加载项中使用 NAA。 我们邀请你在测试或开发环境中试用 NAA,并欢迎通过 GitHub 提供有关体验的反馈 (请参阅本页末尾的 反馈 部分) 。
有关在 Microsoft Teams 中使用 NAA 的信息,请参阅 Microsoft Teams 中的嵌套应用身份验证。
注册单页应用程序
你需要在Azure 门户上为加载项创建Microsoft Azure 应用注册。 应用注册必须至少具有以下条件:
- 名称
- 支持的帐户类型
- SPA 重定向
如果外接程序需要 NAA 和 SSO 以外的其他应用注册,请参阅 单页应用程序:应用注册。
通过 SPA 重定向添加受信任的代理
若要启用 NAA,应用注册必须包含特定的重定向 URI,以向Microsoft 标识平台指示加载项允许自己由受支持的主机代理。 应用程序的重定向 URI 必须为 单页应用程序 类型,并且符合以下方案。
brk-multihub://your-add-in-domain
域必须仅包含源,而不能包含其子路径。 例如:
✔️ brk-multihub://localhost:3000
✔️ brk-multihub://www.contoso.com
❌ brk-multihub://www.contoso.com/go
受信任的代理组在设计上是动态的,将来可以更新,以包括加载项可能使用 NAA 流的其他主机。 目前,brk-multihub 组包括 Office Word、Excel、PowerPoint、Outlook 和 Teams (,用于在) 内激活 Office。
配置 MSAL 配置以使用 NAA
通过在 MSAL 中调用 createNestablePublicClientApplication 函数,将外接程序配置为使用 NAA。 MSAL 返回可嵌套在本机应用程序主机中的公共客户端应用程序, (例如,Outlook) 获取应用程序的令牌。
以下步骤演示如何在使用 taskpane.js (Office 外接程序任务窗格项目) 生成的yo office项目中的 或 taskpane.ts 文件中启用 NAA。
将
@azure/msal-browser包添加到dependencies项目的 文件的 部分package.json。 有关此包的详细信息,请参阅 适用于 Browser-Based Single-Page 应用程序的 Microsoft JavaScript (MSAL.js) 身份验证库。 我们建议使用最新版本的包 (在上次更新时,它是 3.26.0) 。"dependencies": { "@azure/msal-browser": "^3.27.0", ...保存并运行
npm install以安装@azure/msal-browser。将以下代码添加到 或
taskpane.ts文件的顶部taskpane.js。 这将导入 MSAL 浏览器库。import { createNestablePublicClientApplication } from "@azure/msal-browser";
初始化公共客户端应用程序
接下来,需要初始化 MSAL 并获取 公共客户端应用程序的实例。 这用于在需要时获取访问令牌。 建议将创建公共客户端应用程序的代码放在 方法中 Office.onReady 。
Office.onReady在函数中,添加对createNestablePublicClientApplication的调用,如下所示。 将Enter_the_Application_Id_Here占位符替换为之前保存的 Azure 应用 ID。let pca = undefined; Office.onReady(async (info) => { if (info.host) { document.getElementById("sideload-msg").style.display = "none"; document.getElementById("app-body").style.display = "flex"; document.getElementById("run").onclick = run; // Initialize the public client application pca = await createNestablePublicClientApplication({ auth: { clientId: "Enter_the_Application_Id_Here", authority: "https://login.microsoftonline.com/common" }, }); } });
注意
前面的代码示例将 授权 设置为 common,这支持工作和学校帐户或个人Microsoft帐户。 如果要配置单个租户或其他帐户类型,请参阅 应用程序配置选项 ,了解其他颁发机构选项。
获取第一个令牌
MSAL.js 通过 NAA 获取的令牌将为 Azure 应用注册 ID 颁发。 在此代码示例中,你将获取Microsoft图形 API的令牌。 如果用户具有具有Microsoft Entra ID则以无提示方式获取令牌。 否则,库会提示用户以交互方式登录。 然后,该令牌用于调用Microsoft图形 API。
以下步骤显示了用于获取令牌的模式。
- 指定范围。 NAA 支持增量和动态同意,因此始终请求代码完成其任务所需的最小范围。
- 调用
acquireTokenSilent。 这将获取令牌,而无需用户交互。 - 如果
acquireTokenSilent失败,请调用acquireTokenPopup以显示用户的交互式对话。acquireTokenSilent如果令牌过期,或者用户尚未同意所有请求的范围,则可能会失败。
以下代码演示如何在自己的项目中实现此身份验证模式。
将
run或taskpane.ts中的taskpane.js函数替换为以下代码。 代码指定读取用户文件所需的最小范围。async function run() { // Specify minimum scopes needed for the access token. const tokenRequest = { scopes: ["Files.Read", "User.Read", "openid", "profile"], }; let accessToken = null; // TODO 1: Call acquireTokenSilent. // TODO 2: Call acquireTokenPopup. // TODO 3: Log error if token still null. // TODO 4: Call the Microsoft Graph API. }重要
令牌请求必须包含范围,而不仅仅是
offline_access、openid、profile或email。 可以使用上述范围的任意组合,但必须至少包含一个附加范围。 否则,令牌请求可能会失败。将
TODO 1替换为下面的代码。 此代码调用acquireTokenSilent以获取访问令牌。try { console.log("Trying to acquire token silently..."); const userAccount = await pca.acquireTokenSilent(tokenRequest); console.log("Acquired token silently."); accessToken = userAccount.accessToken; } catch (error) { console.log(`Unable to acquire token silently: ${error}`); }将
TODO 2替换为下面的代码。 此代码检查是否获取了访问令牌。 否则,它将尝试通过调用acquireTokenPopup以交互方式获取访问令牌。if (accessToken === null) { // Acquire token silent failure. Send an interactive request via popup. try { console.log("Trying to acquire token interactively..."); const userAccount = await pca.acquireTokenPopup(tokenRequest); console.log("Acquired token interactively."); accessToken = userAccount.accessToken; } catch (popupError) { // Acquire token interactive failure. console.log(`Unable to acquire token interactively: ${popupError}`); } }将
TODO 3替换为下面的代码。 如果无提示登录和交互式登录都失败,请记录错误并返回。// Log error if both silent and popup requests failed. if (accessToken === null) { console.error(`Unable to acquire access token.`); return; }
调用 API
获取令牌后,使用它调用 API。 以下示例演示如何使用 Authorization 标头中附加的令牌调用 fetch Microsoft 图形 API。
将
TODO 4替换为下面的代码。// Call the Microsoft Graph API with the access token. const response = await fetch( `https://graph.microsoft.com/v1.0/me/drive/root/children?$select=name&$top=10`, { headers: { Authorization: accessToken }, } ); if (response.ok) { // Write file names to the console. const data = await response.json(); const names = data.value.map((item) => item.name); // Be sure the taskpane.html has an element with Id = item-subject. const label = document.getElementById("item-subject"); // Write file names to task pane and the console. const nameText = names.join(", "); if (label) label.textContent = nameText; console.log(nameText); } else { const errorText = await response.text(); console.error("Microsoft Graph call failed - error text: " + errorText); }
将上述所有代码添加到 run 函数后,请确保任务窗格上的按钮调用函数 run 。 然后,你可以旁加载加载项并试用代码。
什么是嵌套应用身份验证
嵌套应用身份验证为嵌套在受支持的Microsoft应用程序内的应用程序启用 SSO。 例如,Windows 上的 Excel 在 Web 视图中运行加载项。 在此方案中,外接程序是在 Excel(主机)中运行的嵌套应用程序。 NAA 还支持 Teams 中的嵌套应用。 例如,如果 Teams 选项卡托管 Excel,并且加载了加载项,则它将嵌套在 Excel 中,Excel 中也嵌套在 Teams 中。 同样,NAA 支持此嵌套方案,你可以访问 SSO 来获取已登录用户的用户标识和访问令牌。
最佳做法
将 MSAL.js 与 NAA 配合使用时,建议采用以下最佳做法。
尽可能使用无提示身份验证
MSAL.js 提供了一种方法, acquireTokenSilent 该方法通过发出无提示令牌请求来处理令牌续订,而无需提示用户。 方法首先查找有效的缓存令牌。 如果找不到,库会向Microsoft Entra ID发出无提示请求,如果存在活动用户会话,则会返回新的令牌。
在某些情况下, acquireTokenSilent 方法获取令牌的尝试会失败。 例如,存在一个过期的用户会话与Microsoft Entra ID或用户更改密码,这需要用户交互。 当 acquireTokenSilent 失败时,需要调用交互式 acquireTokenPopup 令牌方法。
当 NAA 不受支持时进行回退
虽然我们努力在整个Microsoft生态系统中提供与这些流的高度兼容性,但您的外接程序可能加载到不支持 NAA 的旧版 Office 主机中。 在这些情况下,加载项不支持无缝 SSO,你可能需要回退到对用户进行身份验证的备用方法。 通常,你需要将 MSAL SPA 身份验证模式与 Office JS 对话框 API 一起使用。
使用以下代码检查加载加载项时是否支持 NAA。
Office.context.requirements.isSetSupported("NestedAppAuth", "1.1");
有关详细信息,请参阅以下资源。
- Outlook 示例:如何回退和支持 Internet Explorer 11
- 使用 Office 对话框 API 进行身份验证和授权。
- 适用于 SPA 和 JavaScript 的Microsoft标识示例
- Microsoft各种应用类型和框架的标识示例
NAA 支持的 MSAL.js API
下表显示了在 MSAL 配置中启用 NAA 时支持哪些 API。
| 方法 | 受 NAA 支持 |
|---|---|
acquireTokenByCode |
无 (引发异常) |
acquireTokenPopup |
是 |
acquireTokenRedirect |
无 (引发异常) |
acquireTokenSilent |
是 |
addEventCallback |
是 |
addPerformanceCallback |
无 (引发异常) |
disableAccountStorageEvents |
无 (引发异常) |
enableAccountStorageEvents |
无 (引发异常) |
getAccountByHomeId |
是 |
getAccountByLocalId |
是 |
getAccountByUsername |
是 |
getActiveAccount |
是 |
getAllAccounts |
是 |
getConfiguration |
是 |
getLogger |
是 |
getTokenCache |
无 (引发异常) |
handleRedirectPromise |
否 |
initialize |
是 |
initializeWrapperLibrary |
是 |
loginPopup |
是 |
loginRedirect |
无 (引发异常) |
logout |
无 (引发异常) |
logoutPopup |
无 (引发异常) |
logoutRedirect |
无 (引发异常) |
removeEventCallback |
是 |
removePerformanceCallback |
无 (引发异常) |
setActiveAccount |
否 |
setLogger |
是 |
ssoSilent |
是 |
安全报告
如果发现我们的库或服务存在安全问题,请尽可能详细地向报告问题 secure@microsoft.com 。 你的提交可能有资格通过Microsoft赏金计划获得 赏金 。 请勿将安全问题发布到 GitHub 或任何其他公共站点。 收到问题报告后,我们会立即联系你。 我们鼓励你通过访问 Microsoft技术安全通知 来获取新的安全事件通知,以订阅安全咨询警报。
代码示例
| 示例名称 | Description |
|---|---|
| 使用嵌套应用身份验证进行 SSO 的 Office 外接程序 | 演示如何在 Office 外接程序中使用 NAA 访问已登录用户的 Microsoft Graph API。 |
| 使用嵌套应用身份验证使用 SSO 的 Outlook 外接程序 | 演示如何在 Outlook 外接程序中使用 NAA 访问已登录用户的 Microsoft Graph API。 |
| 使用嵌套应用身份验证在 Outlook 加载项中的事件中实现 SSO | 演示如何在 Outlook 外接程序事件中使用 NAA 和 SSO。 |
| 使用嵌套应用身份验证 (NAA) 和 SSO 将标识声明发送到资源 | 演示如何将已登录用户的标识声明 ((例如名称、电子邮件或唯一 ID) )发送到数据库等资源。 此示例替换旧版Exchange Online令牌的过时模式。 |
| 使用嵌套应用身份验证(包括 Internet Explorer 回退)进行 SSO 的 Outlook 外接程序 | 演示如何在 NAA 不可用且加载项需要支持 仍使用 Internet Explorer 11 的 Outlook 版本时实现回退身份验证策略。 |