使用 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 权限。
运行时的工作方式
下图显示了登录和访问 Graph Microsoft 所涉及的步骤。 整个过程使用 OAuth 2.0 和 JWT 访问令牌。
外接程序的客户端代码调用 Office.js API getAccessToken。 这会告知 Office 主机获取加载项的访问令牌。
如果用户未登录,Office 主机与 Microsoft 标识平台一起为用户提供登录和同意的 UI。
Office 主机从Microsoft标识平台请求访问令牌。
Microsoft标识平台将访问令牌 A 返回到 Office 主机。 访问令牌 A 仅提供对加载项自己的服务器端 API 的访问权限。 它不提供对 Microsoft Graph 的访问权限。
Office 主机将访问令牌 A 返回到加载项的客户端代码。 现在,客户端代码可以对服务器端 API 进行经过身份验证的调用。
客户端代码向服务器端需要身份验证的 Web API 发出 HTTP 请求。 它包括访问令牌 A 作为授权证明。 服务器端代码验证访问令牌 A。
服务器端代码使用 OAuth 2.0 代理流 (OBO) 请求具有Microsoft Graph 权限的新访问令牌。
如果外接程序请求offline_access权限) ,Microsoft标识平台将返回具有Microsoft Graph (权限的新访问令牌 B 和刷新令牌。 服务器可以选择缓存访问令牌 B。
服务器端代码向 Microsoft Graph API 发出请求,并包含有权Microsoft Graph 的访问令牌 B 。
Microsoft Graph 将数据返回给服务器端代码。
服务器端代码将数据返回给客户端代码。
在后续请求中,当对服务器端代码进行经过身份验证的调用时,客户端代码将始终传递访问令牌 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
(如 OfficeRuntime.auth.getAccessToken( { allowConsentPrompt: true } );
)中传递allowConsentPrompt
选项,则如果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标识平台交换令牌。
最佳做法是始终传递到forMSGraphAccess
getAccessToken
外接程序将在 AppSource 中分发并且需要Microsoft Graph 范围。
有关使用 Outlook 加载项的 SSO 的详细信息
如果开发使用 SSO 的 Outlook 加载项并旁加载它进行测试,则即使已授予管理员同意,Office 也会 始终 返回错误 13012 forMSGraphAccess
getAccessToken
( 传递给 )。 因此,在开发 Outlook 加载项时,forMSGraphAccess
应注释掉选项。 在部署到生产环境时,请务必取消注释选项。 只有在 Outlook 中旁加载时,才会发生虚假 13012。
对于 Outlook 加载项,请务必为 Microsoft 365 租户启用新式身份验证。 有关如何执行此操作的信息,请参阅 在 Exchange Online 中启用或禁用 Outlook 的新式身份验证。
Google Chrome 第三方 Cookie 支持
Google Chrome 正在努力为用户提供对其浏览体验的更多控制。 用户将能够在其 Chrome 浏览器中阻止第三方 Cookie。 这将阻止加载项使用任何此类 Cookie。 当加载项对用户进行身份验证时,这可能会导致问题,例如多个登录请求或错误。
有关改进的身份验证体验,请参阅 使用设备状态在浏览器上使用已阻止的第三方 Cookie 改善 SSO 体验。
有关 Google Chrome 推出的详细信息,请参阅 Web 上的隐私沙盒的新路径。