间歇性获取不到AAD Token
Intermittently Can't Get AAD Token
我为 SharePoint Online 创建了一个自定义 Web 部件,它连接到受 AAD 保护的 Web API,然后将结果显示到屏幕上。它运行良好,但一天中有几次在尝试检索访问令牌时停滞不前。它不会抛出异常,它只是挂起。
起初,我的代码反映了 connecting to AAD secured resources in SharePoint 文档中的内容,但是当 AadHttpClient
开始挂起时,我了解到其他人对此有疑问。因此,我更改了我的代码以创建一个 AadTokenProvider
并对其调用 getToken()
以生成一个令牌,我可以在常规 httpClient.get()
请求中手动添加到 header。
这并没有解决问题,但它确实告诉我 getToken()
肯定是它停止的地方。我不确定 getTokenProvider()
是否正在返回导致 getToken()
挂起的奇怪内容,或者 getToken()
是否因与 SharePoint 或 AAD 相关的原因而挂起。
它似乎也经常在一段时间不活动后失败,就像它试图变得陈旧provider/token并且无法更新但我不知道如何确认或如何处理。
为什么我无法可靠地获取令牌?
这是我的代码:
this.context.aadTokenProviderFactory.getTokenProvider()
.then((provider) => {
return provider.getToken('<Client ID for my API>', false); //THIS IS WHERE IT HANGS
})
.then((token) => {
this.context.httpClient
.get('https://www.example.com/api/myAPI/', AadHttpClient.configurations.v1, {
headers: [
['accept', 'application/json'],
['Authorization', 'Bearer ' + token]
]
})
.then((res: HttpClientResponse): Promise<any> => {
return res.json();
})
.then(data => {
//process data
}, (err: any): void => {
this.context.statusRenderer.renderError(this.domElement, err);
});
})
.catch((err) => {
this.context.statusRenderer.renderError(this.domElement, "Failed to retrieve data.");
});
编辑:我注意到当它不起作用时,我会在控制台中收到以下几个错误:
Blocked script execution in '<URL>'
because the document's frame is sandboxed and the 'allow-scripts' permission is not set.
'<URL>'
类似于https://my tenant.sharepoint.com/_forms/spfxsinglesignon.aspx
微软漏洞
经过一些back and forth with Microsoft,我们确认这是一个与底层令牌获取代码相关的错误。显然,身份验证代码中存在 race()
条件,无法正确解析。
截至目前(2020 年 1 月),还没有修复到位,但根据 bug report,大约一个月后应该会有一些准备就绪。
解决方法
我们发现当您的自定义 Web 部件与其他 OOTB Web 部件(如文档库和事件 Web 部件)位于同一页面时,会出现此问题。通过将文档库 Web 部件移动到不同的页面,问题就消失了。
因此,对于遇到此问题的任何人,您应该能够通过将 1 个或多个 OOTB Web 部件与自定义 Web 部件分开来解决该问题。 至少直到错误被修复。
我为 SharePoint Online 创建了一个自定义 Web 部件,它连接到受 AAD 保护的 Web API,然后将结果显示到屏幕上。它运行良好,但一天中有几次在尝试检索访问令牌时停滞不前。它不会抛出异常,它只是挂起。
起初,我的代码反映了 connecting to AAD secured resources in SharePoint 文档中的内容,但是当 AadHttpClient
开始挂起时,我了解到其他人对此有疑问。因此,我更改了我的代码以创建一个 AadTokenProvider
并对其调用 getToken()
以生成一个令牌,我可以在常规 httpClient.get()
请求中手动添加到 header。
这并没有解决问题,但它确实告诉我 getToken()
肯定是它停止的地方。我不确定 getTokenProvider()
是否正在返回导致 getToken()
挂起的奇怪内容,或者 getToken()
是否因与 SharePoint 或 AAD 相关的原因而挂起。
它似乎也经常在一段时间不活动后失败,就像它试图变得陈旧provider/token并且无法更新但我不知道如何确认或如何处理。
为什么我无法可靠地获取令牌?
这是我的代码:
this.context.aadTokenProviderFactory.getTokenProvider()
.then((provider) => {
return provider.getToken('<Client ID for my API>', false); //THIS IS WHERE IT HANGS
})
.then((token) => {
this.context.httpClient
.get('https://www.example.com/api/myAPI/', AadHttpClient.configurations.v1, {
headers: [
['accept', 'application/json'],
['Authorization', 'Bearer ' + token]
]
})
.then((res: HttpClientResponse): Promise<any> => {
return res.json();
})
.then(data => {
//process data
}, (err: any): void => {
this.context.statusRenderer.renderError(this.domElement, err);
});
})
.catch((err) => {
this.context.statusRenderer.renderError(this.domElement, "Failed to retrieve data.");
});
编辑:我注意到当它不起作用时,我会在控制台中收到以下几个错误:
Blocked script execution in
'<URL>'
because the document's frame is sandboxed and the 'allow-scripts' permission is not set.
'<URL>'
类似于https://my tenant.sharepoint.com/_forms/spfxsinglesignon.aspx
微软漏洞
经过一些back and forth with Microsoft,我们确认这是一个与底层令牌获取代码相关的错误。显然,身份验证代码中存在 race()
条件,无法正确解析。
截至目前(2020 年 1 月),还没有修复到位,但根据 bug report,大约一个月后应该会有一些准备就绪。
解决方法
我们发现当您的自定义 Web 部件与其他 OOTB Web 部件(如文档库和事件 Web 部件)位于同一页面时,会出现此问题。通过将文档库 Web 部件移动到不同的页面,问题就消失了。
因此,对于遇到此问题的任何人,您应该能够通过将 1 个或多个 OOTB Web 部件与自定义 Web 部件分开来解决该问题。 至少直到错误被修复。