Adal js 库 - this.adalService.acquireToken 方法在首次登录时提供 "Token renewal operation failed due to timeout"

Adal js Library - this.adalService.acquireToken method giving "Token renewal operation failed due to timeout" on first time login

虽然有一些link与此问题相关但我没有找到任何相关答案,所以希望这次有人回答。

场景如下,在我的 Angular 应用程序中,我使用的是 adal-angular4,它是 Adal.js[= 的包装器36=]

问题 : this.adalService.acquireToken 方法仅在首次登录时出现。我收到超时错误,但登录后如果我要刷新页面,则 this.adalService.acquireToken 方法正常工作,有趣的部分如下。

  1. 问题只出现在部署环境中不在本地主机中。
  2. 错误 "Token renewal operation failed due to timeout" 仅在网络缓慢或随机时间时出现

这是我的请求拦截器服务

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> | Observable<HttpSentEvent | HttpHeaderResponse
| HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
if (req && req.params instanceof CustomAuthParams && req.params.AuthNotRequired) {
  return this.handleAuthentication(req, next, null);
} else {
  if (!this.adalService.userInfo.authenticated) {
    console.log(req, 'Cannot send request to registered endpoint if the user is not authenticated.');
  }
  var cachedToken = this.adalService.getCachedToken(environment.authSettings.clientId);
  console.log('cachedToken', cachedToken);
  if (cachedToken) {
    return this.adalService.acquireToken(resourceURL).timeout(this.API_TIMEOUT).pipe(
      mergeMap((token: string) => {
        return this.handleAuthentication(req, next, token);
      })
    ).catch(err => { console.log('acquire token error', err); return throwError(err) })
  } else {
    this.adalService.login();
  }
}

}

好吧,折腾了1-2天,我找到了根本原因。所以发布这个答案,以便对其他人有所帮助。

adal-angular4 库正在使用 1.0.15 版本的 adal-angular 这是旧版本,其中 loadFrameTimeout 的默认超时是 6 秒 并且在这个版本中没有配置增加loadFrameTimeout。请看下面link

Adal configurations

现在在第一次登录时会发生很多步骤。

  1. 身份验证后,应用程序通过 azure AD 重定向到配置的 URI,通过在回复 URL.
  2. 中附加 ID 和访问令牌
  3. 然后库在本地存储或会话存储中设置所有这些令牌,具体取决于配置。
  4. 然后您的应用程序加载并开始调用 webapi。现在这里发生了有趣的事情,对于每个请求,我都调用 acquireToken 方法来对抗 webapi 应用程序,因此如果网络速度较慢,acquireToken 调用将提供超时错误,因为 6 秒 有时是不够的。但是对于某些 API 它将能够获得令牌。
  5. 现在第一次调用 acquireToken 方法需要时间,但对于后续请求,它会从 缓存 中获取令牌(如果可用),因此超时错误仅在第一次出现,之后才出现.

所以,在这个库中目前没有办法增加 loadFrameTimeout 所以我用了 Angular5 warpper 使用 1.0.17 版本的 adal-angular 我们可以增加 loadFrameTimeout 解决了我的问题。