使用 SSO 对 Microsoft Graph 授权

用户使用其个人 Microsoft 帐户或Microsoft 365 教育版或工作帐户登录到 Office。 在 Office 加载项中获取对 Microsoft Graph 的访问权限的最佳方式是使用用户的 Office 登录凭据。 这使用户能够访问其 Microsoft Graph 数据,而无需再次登录。

SSO 和 Microsoft Graph 的加载项体系结构

除了托管 Web 应用程序的页面和 JavaScript 之外,外接程序还必须以相同的完全限定的域名托管一个或多个 Web API,这些 API 可获取 Microsoft Graph 的访问令牌,并向它发出请求。

外接程序清单包含 WebApplicationInfo<> 元素,该元素向 Office 提供重要的 Azure 应用注册信息,包括加载项所需的 Microsoft Graph 权限。

运行时的工作方式

下图显示了登录和访问 Microsoft Graph 所涉及的步骤。 整个过程使用 OAuth 2.0 和 JWT 访问令牌。

显示 SSO 过程的关系图。

  1. 外接程序的客户端代码调用 Office.js API getAccessToken。 这会告知 Office 主机获取加载项的访问令牌。

    如果用户未登录,Office 主机与Microsoft 标识平台一起为用户提供登录和同意的 UI。

  2. Office 主机从Microsoft 标识平台请求访问令牌。

  3. Microsoft 标识平台将访问令牌 A 返回到 Office 主机。 访问令牌 A 仅提供对加载项自己的服务器端 API 的访问权限。 它不提供对 Microsoft Graph 的访问权限。

  4. Office 主机将访问令牌 A 返回到加载项的客户端代码。 现在,客户端代码可以对服务器端 API 进行经过身份验证的调用。

  5. 客户端代码向服务器端需要身份验证的 Web API 发出 HTTP 请求。 它包括访问令牌 A 作为授权证明。 服务器端代码验证访问令牌 A

  6. 服务器端代码使用 OAuth 2.0 代理流 (OBO) 请求具有 Microsoft Graph 权限的新访问令牌。

  7. 如果外接程序请求offline_access权限) ,Microsoft 标识平台将返回具有 Microsoft Graph (权限的新访问令牌 B 和刷新令牌。 服务器可以选择缓存访问令牌 B

  8. 服务器端代码向 Microsoft 图形 API发出请求,并包含具有 Microsoft Graph 权限的访问令牌 B

  9. Microsoft Graph 将数据返回给服务器端代码。

  10. 服务器端代码将数据返回给客户端代码。

在后续请求中,当对服务器端代码进行经过身份验证的调用时,客户端代码将始终传递访问令牌 A 。 服务器端代码可以缓存令牌 B ,以便它不需要在将来的 API 调用中再次请求它。

开发可访问 Microsoft Graph 的 SSO 加载项

开发一个访问 Microsoft Graph 的外接程序,就像使用 SSO 的任何其他应用程序一样。 有关全面说明,请参阅 为 Office 加载项启用单一登录。区别在于加载项必须具有服务器端 Web API。

根据所用的语言和框架,可能存在一些库,可简化必须编写的服务器端代码。 代码应执行以下操作:

  • 每次从客户端代码传递访问令牌 A 时,请验证访问令牌 A 。 有关详细信息,请参阅验证访问令牌
  • 通过调用Microsoft 标识平台启动 OAuth 2.0 代表流 (OBO) ,其中包括访问令牌、有关用户的一些元数据以及外接程序的凭据 (其 ID 和机密) 。 有关 OBO 流的详细信息,请参阅 Microsoft 标识平台 和 OAuth 2.0 代表流
  • (可选)流完成后,缓存具有 Microsoft Graph 权限的返回访问令牌 B 。 如果加载项对 Microsoft Graph 进行多次调用,则需要执行此操作。 有关详细信息,请参阅 使用 Microsoft 身份验证库 (MSAL) 获取和缓存令牌
  • 通过将可能缓存的 () 访问令牌 B 传递给 Microsoft Graph,创建一个或多个获取 Microsoft Graph 数据的 Web API 方法。

有关详细演练和应用场景的示例,请参阅:

在 Microsoft AppSource 中分发已启用 SSO 的加载项

当 Microsoft 365 管理员从 AppSource 获取加载项时,管理员可以通过 集成应用 重新分发它,并向该外接程序授予管理员同意以访问 Microsoft Graph 范围。 但是,最终用户也可以直接从 AppSource 获取加载项,在这种情况下,用户必须向外接程序授予许可。 这可能会造成我们为其提供解决方案的潜在性能问题。

如果代码在 调用 getAccessToken中传递allowConsentPrompt选项(如 OfficeRuntime.auth.getAccessToken( { allowConsentPrompt: true } );),则如果Microsoft 标识平台向 Office 报告尚未向加载项授予同意,Office 可以提示用户同意。 但是,出于安全原因,Office 只能提示用户同意 Microsoft Graph profile 范围。 Office 无法提示同意其他 Microsoft Graph 范围,甚至 User.Read无法。 这意味着,如果用户在提示时授予同意,Office 将返回访问令牌。 但是,尝试使用其他 Microsoft Graph 范围交换新访问令牌的访问令牌失败,并出现错误AADSTS65001,这意味着尚未授予对 Microsoft Graph 作用域 (同意) 。

注意

如果管理员关闭了最终用户同意 { allowConsentPrompt: true } ,即使对于 profile 范围而言,同意请求仍可能失败。 有关详细信息,请参阅 使用 Azure Active Directory 配置最终用户同意应用程序的方式

你的代码可以通过回退到备用身份验证系统来处理此错误,这会提示用户同意 Microsoft Graph 范围。 有关代码示例,请参阅 创建使用单一登录的 Node.js Office 外接程序创建使用单一登录的 ASP.NET Office 外接程序 及其链接到的示例。 整个过程需要多次往返Microsoft 标识平台。 若要避免这种性能损失,请在 的调用getAccessToken中包含 forMSGraphAccess 选项,OfficeRuntime.auth.getAccessToken( { forMSGraphAccess: true } )例如 。 这向 Office 发出信号,表明外接程序需要 Microsoft Graph 范围。 Office 将要求Microsoft 标识平台验证是否已向加载项授予对 Microsoft Graph 范围的许可。 如果有,则返回访问令牌。 如果没有,则 的调用 getAccessToken 将返回错误 13012。 代码可以通过立即回退到备用身份验证系统来处理此错误,而不会尝试与Microsoft 标识平台交换令牌。

最佳做法是,始终传递到forMSGraphAccessgetAccessToken外接程序将在 AppSource 中分发并且需要 Microsoft Graph 范围时。

有关使用 Outlook 加载项的 SSO 的详细信息

如果开发使用 SSO 的 Outlook 加载项并旁加载它进行测试,则即使已授予管理员同意,Office 也会 始终 返回错误 13012 forMSGraphAccessgetAccessToken ( 传递给 )。 因此,在开发 Outlook 加载项forMSGraphAccess应注释掉选项。 在部署到生产环境时,请务必取消注释选项。 只有在 Outlook 中旁加载时,才会发生虚假 13012。

对于 Outlook 加载项,请务必为 Microsoft 365 租户启用新式身份验证。 有关如何执行此操作的信息,请参阅在 Exchange Online 中启用或禁用 Outlook 的新式身份验证

Google Chrome 在 2024 年逐步淘汰第三方 Cookie,并引入了一项名为“跟踪防护”的功能。 如果在 Chrome 浏览器中启用了跟踪防护,则加载项将无法使用任何第三方 Cookie。 加载项在对用户进行身份验证时可能会遇到问题,例如多个登录请求或错误。

有关改进的身份验证体验,请参阅 使用设备状态在浏览器上使用已阻止的第三方 Cookie 改善 SSO 体验

有关 Google Chrome 推出的详细信息,请参阅以下资源:

另请参阅