Azure ad b2c MSAL acquireTokenSilent后跟acquireTokenPopup会导致弹出窗口中出现错误请求

Azure ad b2c MSAL acquireTokenSilent后跟acquireTokenPopup会导致弹出窗口中出现错误请求,azure-ad-b2c,msal,msal.js,Azure Ad B2c,Msal,Msal.js,我们正在使用MSAL.js对Azure AD B2C实例的用户进行身份验证。用户可以使用本地帐户,也可以使用来自其他Azure Active Directory实例的凭据登录 登录后,我们的SPA使用acquireTokenSilent获取访问令牌,并返回acquireTokenPopup 我们注意到,当acquireTokenSilent超时时,仍可以在后台检索令牌,并且应用程序本地存储将使用令牌更新。然而,在应用程序中,我们继续调用acquireTokenPopup。用户在acquireTo

我们正在使用MSAL.js对Azure AD B2C实例的用户进行身份验证。用户可以使用本地帐户,也可以使用来自其他Azure Active Directory实例的凭据登录

登录后,我们的SPA使用acquireTokenSilent获取访问令牌,并返回acquireTokenPopup

我们注意到,当acquireTokenSilent超时时,仍可以在后台检索令牌,并且应用程序本地存储将使用令牌更新。然而,在应用程序中,我们继续调用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));
        });
    });
  }
函数getMsalAuthenticationManager(权限:IMSALAuthorityConfig):IMsalAuthenticationManager{
返回新的MsalAuthenticationManager(
appConfig.msal.clientId,
授权、签字人授权,
authority.passwordResetAuthority,
{
loadFrameTimeout:15000,
端点:端点映射,
cacheLocation:appConfig.msal.cacheLocation//localStorage
}
);
}
//MsalAuthenticationManager构造函数
建造师(
私有应用程序ID:string,
权威?:字符串,
authorityForPasswordReset?:字符串,
M开发?:imsal选项
) {
var onTokenReceived=authorityForPasswordReset
?(errorDesc:string,token:string,error:string,tokenType:string)=>{
//当用户单击忘记密码链接时,此应用程序将返回以下错误。
//在这种情况下,我们需要使用密码重置策略重新实例化UserAgentApplication对象。
if(errorDesc&&errorDesc.indexOf(“AADB2C90118”)>-1){
此.msal=new UserAgentApplication(
应用程序ID,
授权密码重置,
收到,
开发
);
这个;
}
}
:(errorDesc:string,token:string,error:string,tokenType:string)=>{};
this.msal=新的用户代理应用程序(应用程序ID、权限、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);//获取特定端点的范围
this.acquireToken=this.acquireToken.bind(this);
}
公共acquireToken(作用域:字符串[]):承诺{
返回新承诺((解决、拒绝)=>{
这个
.acquireTokenSilent(作用域)
.then((accessToken:string)=>resolve(accessToken))
.catch((acquireTokenSilentError:string)=>{
这个
.acquireTokenPopup(范围)
.then((accessToken:string)=>resolve(accessToken))
.catch((acquireTokenPopupError:string)=>reject(acquireTokenPopupError));
});
});
}

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