MSAL的acquireTokenSilent和随后的acquireTokenPopup会在弹出窗口中导致错误请求

时间:2018-11-06 11:33:45

标签: azure-ad-b2c msal msal.js

我们正在使用MSAL.js来验证用户到Azure AD B2C实例的身份。用户可以使用本地帐户,也可以使用其凭据从另一个Azure Active Directory实例登录。

已登录,我们的SPA使用acquireTokenSilent获取访问令牌,并回退到AcquisitionTokenPopup。

我们注意到的是,当AcquisitionTokenSilent超时时,仍可以在后台检索令牌,并且使用令牌更新应用程序本地存储。但是,在应用程序中,我们继续调用了acquireTokenPopup。用户在acquireTokenPopup中输入其凭据后,弹出窗口将显示“错误请求”。用户可以关闭弹出窗口,如果刷新应用程序,则现在将登录。

对于我们的用户而言,这种体验不是很好的体验。

只是想知道这是一个已知问题还是预期的行为?

以下是我们代码中的相关摘录。我们将UserAgentApplication包装在MsalAuthenticationManager对象中。

function getMsalAuthenticationManager(authority: IMSALAuthorityConfig): IMsalAuthenticationManager {
  return new MsalAuthenticationManager(
    appConfig.msal.clientId,
    authority.signUpOrSignInAuthority,
    authority.passwordResetAuthority,
    {
      loadFrameTimeout: 15000,
      endPoints: endPointsMap,
      cacheLocation: appConfig.msal.cacheLocation // localStorage
    }
  );
}

// MsalAuthenticationManager constructor
  constructor(
    private applicationId: string,
    authority?: string,
    authorityForPasswordReset?: string,
    msalOptions?: IMsalOptions
  ) {
    var onTokenReceived = authorityForPasswordReset
      ? (errorDesc: string, token: string, error: string, tokenType: string) => {
          // When the user clicks on the forgot password link, the following error is returned to this app.
          // In this case we need to re-instantiate the UserAgentApplication object with the Password Reset policy.
          if (errorDesc && errorDesc.indexOf("AADB2C90118") > -1) {
            this._msal = new UserAgentApplication(
              applicationId,
              authorityForPasswordReset,
              onTokenReceived,
              msalOptions
            );

            this.signIn();
          }
        }
      : (errorDesc: string, token: string, error: string, tokenType: string) => {};

    this._msal = new UserAgentApplication(applicationId, authority, onTokenReceived, msalOptions);

    this.acquireToken = this.acquireToken.bind(this);
    this.signIn = this.signIn.bind(this);
    this.signOut = this.signOut.bind(this);
    this.getResourceForEndpoint = this.getResourceForEndpoint.bind(this); // Gets the scope for a particular endpoint
    this.acquireToken = this.acquireToken.bind(this);
  }

  public acquireToken(scopes: string[]): Promise<string> {
    return new Promise((resolve, reject) => {
      this._msal
        .acquireTokenSilent(scopes)
        .then((accessToken: string) => resolve(accessToken))
        .catch((acquireTokenSilentError: string) => {
          this._msal
            .acquireTokenPopup(scopes)
            .then((accessToken: string) => resolve(accessToken))
            .catch((acquireTokenPopupError: string) => reject(acquireTokenPopupError));
        });
    });
  }

1 个答案:

答案 0 :(得分:0)

我有一个类似的问题,原因是令牌仍然存在但已过期,并且由于msal.js不检查令牌过期,因此您将被视为已登录,但是您的令牌实际上是无效的,并且带有承载的httpRequests将因未授权而失败。您应该记录acquiretokenSilent错误并查找“ AADB2C90077”错误,如果令牌已过期,请调用logout()。