使用 Office 对话框 API 进行身份验证和授权

始终使用 Office 对话框 API 通过 Office 加载项对用户进行身份验证和授权。 如果在无法使用单一登录 (SSO) 时实现回退身份验证,则还必须使用 Office 对话框 API。

在 Office web 版 中打开时,Office 加载项在 iframe 中运行。 许多标识机构(也称为安全令牌服务 (STS) )阻止其登录页面在 iframe 中打开。 这些帐户包括 Google、Facebook,以及受以前为 Azure AD V 2.0) Microsoft 标识平台 (保护的服务,例如 Microsoft 帐户、Microsoft 365 教育版或工作帐户或其他通用帐户。 此外,当 Office 加载项在 Windows 或 Mac 上的 Office 中运行时,在 Web 视图中实现的安全功能可能会阻止登录页面正常工作。

若要使授权正常工作,登录页必须在单独的浏览器或 Webview 控件实例中打开。 这就是 Office 提供 Office 对话框 API 的原因,特别是 displayDialogAsync 方法。

注意

使用此 API 打开的对话具有以下特征。

  • 它是非模态
  • 它是完全独立于任务窗格的浏览器实例,这意味着:
    • 它有自己的运行时环境以及窗口对象和全局变量。
    • 没有与任务窗格共享的执行环境。
    • 它不会与任务窗格) 的 Window.sessionStorage 属性 (共享相同的会话存储。
  • 对话框中打开的第一页必须与任务窗格托管在同一域中,包括协议、子域和端口(如果有)。
  • 对话框可以使用 messageParent 方法将信息发送回任务窗格。 建议仅从与任务窗格托管在同一域中的页面调用此方法,包括协议、子域、端口。 否则,调用方法和处理消息的方式会出现复杂情况。 有关详细信息,请参阅向主机运行时间跨域消息传递

默认情况下,对话框在新的 Web 视图控件中打开,而不是在 iframe 中打开。 这可确保它可以打开标识提供程序的登录页面。 如本文稍后部分所示,Office 对话框的特征对如何使用身份验证或授权库(例如 Microsoft 身份验证库 (MSAL) 和 Passport)具有影响。

注意

若要将对话框配置为在浮动 iframe 中打开,请在调用 displayDialogAsync中传递 displayInIframe: true 选项。 使用对话框 API 登录时, 请不要这样做。

使用 Office 对话框的身份验证流

下面是一个典型的身份验证流程。

显示任务窗格与对话框浏览器进程之间的关系的关系图。

  1. 对话框中打开的第一页是外接程序域中托管的页面 (或其他资源) ;即与任务窗格窗口相同的域。 此页面的 UI 只能显示“请稍候,我们正在将你重定向到可在其中登录到 NAME-OF-PROVIDER 的页面。此页面中的代码构造标识提供者登录页的 URL,这些信息要么按照将 信息传递给 对话框中所述传递给对话框,要么硬编码到外接程序的配置文件(如 web.config 文件)。
  2. 然后,对话框窗口重定向到登录页。 URL 包含一个查询参数,用于告知身份提供程序在用户登录后将对话框窗口重定向到特定页面。 在本文中,我们将此页面称为 redirectPage.html。 在此页上,登录尝试的结果可以通过调用 messageParent 传递到任务窗格。 建议此页与主机窗口位于同一域中
  3. 身份提供程序的服务处理来自对话框窗口的传入 GET 请求。 如果用户已经登录,它会立即将窗口重定向到 redirectPage.html,并包括用户数据作为查询参数。 如果用户尚未登录,提供程序的登录页会显示在窗口中,以便用户登录。 对于大多数提供程序,如果用户无法成功登录,则提供程序在对话框窗口中显示错误页,并且不会重定向到 redirectPage.html。 用户必须通过选择右上角的 X 来关闭窗口。 如果用户成功登录,则对话框窗口会重定向到 redirectPage.html,并包括用户数据会作为查询参数。
  4. redirectPage.html 页面打开时,它会调用 messageParent 向任务窗格页报告登录是否成功,而且还会视情况报告用户数据或错误数据。 其他可能的消息包括传递访问令牌或告知任务窗格信息位于存储中。
  5. DialogMessageReceived 事件在任务窗格页中触发,其处理程序关闭对话框窗口,并可能对消息进行进一步处理。

支持多个标识提供程序

如果你的外接程序为用户提供了选择提供程序(如 Microsoft 帐户、Google 或Facebook),则需要本地首页 (请参阅上一节) ,该部分为用户提供了选择提供程序的 UI。 用户的选择会触发登录 URL 的构建并重定向到该 URL。

加载项中对外部资源的授权

在现代网络中,用户和 Web 应用程序是安全主体。 应用程序拥有自己的身份以及对联机资源(如 Microsoft 365、Google Plus、Facebook 或 LinkedIn)的权限。 在部署前,需要先向资源提供程序注册应用程序。 注册内容包括:

  • 应用程序访所需的权限的列表。
  • 当应用访问服务时,资源服务应向其返回访问令牌的 URL。

如果用户在应用中调用访问资源服务中用户数据的函数,系统会先提示用户登录相应服务,再提示用户向应用授予访问用户资源所需的权限。 然后,服务将登录窗口重定向到先前注册的 URL,并传递访问令牌。 应用使用访问令牌访问用户资源。

可以使用 Office 对话框 API 来管理此过程,具体方法是使用与用户登录流程类似的流程。 唯一区别在于:

  • 如果用户以前未向应用程序授予所需的权限,则登录后,系统会在对话框中提示用户执行此操作。
  • 对话框窗口中的代码将访问令牌发送到主机窗口,方法是使用 messageParent 发送字符串化访问令牌,或者存储访问令牌,主机窗口可以在其中检索该令牌 (并使用 messageParent 告知主机窗口令牌) 可用。 令牌具有时间限制,但在持续期间,主机窗口可以使用它直接访问用户资源,而无需进一步提示。

示例中列出了使用 Office 对话框 API 来实现此目的的一些身份验证示例加载项。

通过对话框使用身份验证库

由于 Office 对话框和任务窗格在不同的 浏览器运行时实例中运行,因此必须使用身份验证/授权库的方式不同于在同一窗口中进行身份验证和授权时它们的使用方式。 以下部分介绍了可以使用和不能使用这些库的方法。

通常无法使用库的内部缓存来存储令牌

通常,身份验证相关库提供内存缓存来存储访问令牌。 如果对资源提供程序(例如 Google、Microsoft Graph、Facebook 等)进行了后续调用,则库将首先检查以确定其缓存中的令牌是否已过期。 如果未过期,库将返回缓存的令牌,而不是为新令牌再执行一次到 STS 的往返行程。 但此模式在 Office 加载项中不可用。由于登录过程发生在 Office 对话框的浏览器实例中,因此令牌缓存位于该实例中。

与此非常密切相关的是,库通常会同时提供用于获取令牌的交互式和“无提示”方法。 如果你既可以进行身份验证,也可以在同一浏览器实例中对资源进行数据调用,则代码会调用无提示方法来获取令牌,然后马上将该令牌添加到数据调用。 无提示方法会检查缓存是否有中未过期的令牌,并将其返回(如果有)。 否则,无提示方法调用重定向到 STS 登录的交互式方法。 登录完成后,交互式方法将返回令牌,但也将其缓存在内存中。 但是,在使用 Office 对话框 API 时,对资源的数据调用(它将调用无提示方法)位于任务窗格的浏览器实例中。 库的令牌缓存在该实例中不存在。

作为替代方法,加载项的对话框浏览器实例可以直接调用库的交互式方法。 当该方法返回令牌时,代码必须将令牌显式存储在任务窗格的浏览器实例可以检索它的某个位置,例如 本地存储 或服务器端数据库。

注意

对浏览器安全性的更改会影响令牌处理策略。

  • 如果外接程序在 Office web 版 Microsoft Edge 旧版 (非Chromium) 或 Safari 浏览器中运行,则对话框和任务窗格不会共享相同的本地存储,因此不能用于在它们之间进行通信。
  • 从基于 Chromium 的浏览器(例如 Chrome 和 Edge)的版本 115 开始,存储分区将进行测试,以防止特定侧通道跨站点跟踪 (另请参阅 Microsoft Edge 浏览器策略) 。 这意味着,存储 API 存储的数据(例如本地存储)仅适用于具有相同源和相同顶级站点的上下文。 若要解决此问题,请在浏览器中转到 chrome://flagsedge://flags,然后将 实验性第三方存储分区 (#第三方存储分区) 标志设置为 “已禁用”。 如果可能,我们建议使用 messageParentmessageChild 方法在对话和任务窗格之间传递数据,如在 Office 外接程序中使用 Office 对话框 API 中所述。

另一种选择是使用 messageParent 方法将令牌传递到任务窗格。 仅当交互式方法将访问令牌存储在代码可以读取的位置时,才可以使用此替代选项。 有时,库的交互式方法设计为将令牌存储到代码无法访问的对象的私有属性中。

通常无法使用库的“身份验证上下文”对象

通常情况下,与身份验证相关的库有一种方法,该方法既能够以交互方式获取令牌,也会创建方法返回的“身份验证上下文”对象。 令牌是对象的一个属性(可能是私有属性,并且无法直接从代码中访问)。 该对象具有从资源中获取数据的方法。 这些方法将令牌包括在其对资源提供程序(例如 Google、Microsoft Graph、Facebook 等)进行的 HTTP 请求中。

这些身份验证上下文对象以及创建它们的方法在 Office 外接程序中不可用。由于登录发生在 Office 对话框的浏览器实例中,因此必须在此处创建 对象。 但对资源的数据调用位于任务窗格浏览器实例中,因此无法将对象从一个实例获取到另一个实例。 例如,无法通过 messageParent 传递对象,因为 messageParent 只能传递字符串值。 无法可靠地将包含方法的 JavaScript 对象字符串化。

如何将库与 Office 对话框 API 结合使用

大多数库提供了更低抽象级别的 API 作为单一“身份验证相关”对象的补充(或取代这些对象),可让代码创建不太单一的整体帮助程序对象。 例如, MSAL.NET v. 3.x.x 具有用于构造登录 URL 的 API,以及另一个用于构造 AuthResult 对象的 API,该对象包含代码可访问的属性中的访问令牌。 有关 Office 加载项中的 MSAL.NET 的示例,请参阅: Office 加载项 Microsoft Graph ASP.NETOutlook 加载项 Microsoft Graph ASP.NET。 有关在加载项中使用 msal.js 的示例,请参阅 Office 加载项 Microsoft Graph React

有关身份验证和授权库的详细信息,请参阅 Microsoft Graph:推荐的库其他外部服务:库

示例

另请参阅