使用嵌套应用身份验证在 Office 外接程序中启用 SSO
可以将 MSAL.js 库与嵌套应用身份验证配合使用,以使用 Office 外接程序中的 SSO。 与代表 (OBO) 流,使用嵌套应用身份验证具有多个优势。
- 只需使用 MSAL.js 库,而不需要
getAccessToken
Office.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 (iOS) | GA |
PowerPoint | 预览版 | 预览版 | 预览版 | iPad 上的预览版 | 不适用 |
Word | 预览版 | 预览版 | 预览版 | iPad 上的预览版 | 不适用 |
重要
若要在仍处于预览状态的平台上使用 NAA,请加入 Microsoft 365 预览体验计划 (https://insider.microsoft365.com/join) ,然后选择 当前频道 (预览版) 。 请勿在任何预览平台的生产加载项中使用 NAA。 我们邀请你在测试或开发环境中试用 NAA,并欢迎通过 GitHub 提供有关体验的反馈 (请参阅本页末尾的 反馈 部分) 。
注册单页应用程序
你需要在Azure 门户上为加载项创建Microsoft Azure 应用注册。 应用注册必须至少具有以下条件:
- 名称
- 支持的帐户类型
- SPA 重定向
如果外接程序需要 NAA 和 SSO 以外的其他应用注册,请参阅 单页应用程序:应用注册。
通过 SPA 重定向添加受信任的代理
若要启用 NAA,应用注册必须包含特定的重定向 URI,以向Microsoft 标识平台指示加载项允许自己由受支持的主机代理。 应用程序的重定向 URI 必须为 单页应用程序 类型,并且符合以下方案。
brk-multihub://your-add-in-domain
例如,如果在 localhost 服务器上的端口 3000 上测试加载项,则可使用 brk-multihub://localhost:3000
作为重定向值。
受信任的代理组在设计上是动态的,将来可以更新,以包括加载项可能使用 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.26.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. }
将
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 外接程序中使用 MSAL.js 嵌套应用身份验证 (NAA) 来访问已登录用户的 Microsoft Graph API。 该示例显示已登录用户的姓名和电子邮件。 它还会将用户的 Microsoft OneDrive 帐户中的文件名插入到文档中。 |
使用嵌套应用身份验证使用 SSO 的 Outlook 外接程序 | 演示如何在 Outlook 外接程序中使用 MSAL.js 嵌套应用身份验证 (NAA) 来访问已登录用户的 Microsoft Graph API。 该示例显示已登录用户的姓名和电子邮件。 它还会将用户的 Microsoft OneDrive 帐户中的文件名插入到新的邮件正文中。 |