Office加载项MSAL单点登录SSO:如何刷新访问令牌



如何在Office Addin单一登录解决方案中监控访问令牌的到期情况并刷新它?

MSAL Office外接程序中的单一登录是一个复杂的问题。访问令牌通过调用获得

OfficeRuntime.auth.getAccessToken()

然后使用Microsoft Identity On-Behalf-Of-Flow将访问令牌交换为API的访问令牌。一切都很好。

但是访问令牌过期。OfficeRunetime.auth似乎没有任何管理访问令牌到期和刷新的内容。与它的对应MsalService不同(它在普通的Javascript/Angular web应用程序中运行,而不是在Office加载项中运行),它管理令牌,并且不能在Office加载程序中使用。

每次在API调用之前,我是否只是继续在HTTP侦听器中调用OfficeRuntime.auth.getAccessToken()?我知道getAccessToken()确实首先在缓存中查询AccessToken,然后我是否推断它正在管理该令牌的到期,并返回身份服务器获取新令牌?

还是我完全走错了路?

经过大量的阅读和原型设计,我将回答我自己的问题。

首先,当涉及到MSAL、令牌、声明、范围等以及所有重要的身份验证时,我是一个初学者,我痛苦地蹒跚地完成了这一切。我欢迎所有对此答案的反馈,并将在必要时更新答案

以下是我观察到的:但首先,在我的问题的结论中

OfficeRuntime.auth.getAccessToken()在令牌过期时管理并刷新令牌(对于MSExcel)

背景

  1. 首先,我正在使用MSExcel。Microsoft文档似乎将Excel/Word/PowerPoint组合在一起并处理Outlook不同地我很感谢@Eugene Astafiev对此的回答从Outlook的角度提出问题,但我发现适用于Excel

  2. OfficeAdd-inOfficeRuntime.auth.getAccessToken()返回,Microsoft文档所称的"引导"令牌是一种访问令牌,其中也包含身份令牌。引导令牌可用于代表流(在流中称为"断言"令牌),以将其交换为不同作用域的其他访问令牌。在我的应用程序中,我将if交换为API的访问令牌,让我们将其称为APIAccessToken

  3. 引导令牌和其中的身份令牌都将于到期同时在大约87分钟之后。记录到期时间在Identity Tokens"exp"声明中。我不知道这是不是可在某个地方配置,但关键是两者同时过期。

  4. APIAccessToken(从海外建筑运营管理局流返回的令牌)与引导令牌同时到期(几乎,它似乎在正式到期后10分钟内随机到期)。每次我调用OBO流时,返回的生成APIAccesstoken都是不同的,但仅在后半部分。尽管它们不同,而且不考虑它们是在什么时候生成的,但它们仍然与用来交换它们的引导令牌(断言令牌)同时过期,并且它们都保持有效,并且可使用直到到期时间(即使它们不同)

  5. 除了使用海外建筑运营管理局流之外,在Excel加载项中无法以任何其他方式获取APIAccessToken。这是因为Office Excel中的IFrame和登录重定向存在挑战。Excel提供了getAccessToken()和一个在自己的实例中运行的对话框。(请参阅Office Addin单点登录的MS Excel文档)访问令牌仅对海外建筑运营管理局流有用

  6. MS文档中概述的后备身份验证策略https://learn.microsoft.com/en-us/office/dev/add-ins/develop/sso-in-office-add-ins是绝对必要的,因为当用户没有同意您的SPA和API访问他们的配置文件时,您总是会后退。然而,正如目前所记录的那样,这是不够的。它没有得到MSOffice15的同意,这导致了持续的登录问题。我在这里提出了一个堆栈溢出问题Office Addin Single Sign-In,如何手动添加MSOffice15同意和错误13005,目前已经实现了一个解决方案(我会在该链接上发布它作为回应)。后备方案必须管理三个同意。MSOffice15,您的SPA和API。

刷新令牌1。每次调用OfficeRuntime.auth.getAccessToken()都会返回相同的引导令牌,该令牌具有相同的到期时间,直到到期。当它到期时,我确认此函数会调用Identity Server Endpoint并获得一个新的引导令牌,其中包含一个新身份令牌,其到期时间再次为~87分钟。这是有道理的,因为Microsoft文档声明它存储在Cache中,并由OfficeRuntime.auth.getAccessToken()检索。这使得此函数调用轻量级,并且可以经常调用。

MySolution我从官方MSALInterceptor类派生了一个新类(继承)。每次调用受保护的资源时,我都会调用OfficeRuntime.auth.getAccessToken()如果令牌的到期日已更改,则我知道已颁发了新的引导令牌。然后我调用一些中间件代码来获得一个新的APIAccessToken

我希望这能节省一些时间!最后,我要说的是,我终于让整个单点登录解决方案为Office-Addin SPA(angular)工作,该SPA管理所有同意(办公室、SPA和我的API)。花了8个多星期的时间。现在是星期五下午3点,我正偷偷溜过老板回家:-)

我最近也遇到了同样的问题。您(用户)必须重新启动Outlook才能获得新的访问令牌(未过期)。Office JavaScript API没有为此提供任何方法或属性。你能做的最好的事情就是处理异常并通知用户重新启动主机。

缓存是内存中的缓存。它只有在重新启动Outlook时才被清除。令牌的TTL到期后,令牌将自动超时,但这可能取决于服务器实现。

您可以在技术社区上发布或投票支持现有的功能请求,Office开发团队在进行规划过程时会考虑这些请求。

最新更新