azure-ad-b2c - MSAL acquireTokenSilent 后跟 acquireTokenPopup 在弹出窗口中导致错误请求
问题描述
我们正在使用 MSAL.js 对 Azure AD B2C 实例的用户进行身份验证。用户可以使用本地帐户或使用来自另一个 Azure Active Directory 实例的凭据登录。
登录后,我们的 SPA 使用 acquireTokenSilent 获取访问令牌,并回退到 acquireTokenPopup。
我们注意到的是,当acquireTokenSilent 超时时,仍可能在后台检索token,并用token 更新应用程序本地存储。但是,在应用程序中,我们继续调用了 acquireTokenPopup。用户在acquireTokenPopup 中输入他们的凭据后,弹出窗口会显示“Bad Request”。用户可以关闭弹出窗口,如果他们刷新应用程序,他们现在将登录。
对于我们的用户来说,这种体验并不是很好的体验。
只是想知道这是一个已知问题还是预期行为?
这是我们代码的相关摘录。我们将 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));
});
});
}
解决方案
我有一个类似的问题,原因是令牌仍然存在但已过期,并且由于 msal.js 不检查令牌过期,您将被视为已登录,但您的令牌实际上是无效的,并且您与承载的 httpRequests 将失败为未经授权。您应该记录 acquiretokenSilent 错误并查找“AADB2C90077”错误,如果令牌已过期,请调用 logout()。
推荐阅读
- angular - 如何将表单控件添加到角度 8 中的文本区域
- c# - 如何从类型中获取内部属性?
- regex - 如何选择带空格的句号,但正则表达式的缩写除外?
- react-native - 地图始终位于搜索位置标记的中心
- typescript - 管道函数参数类型被推断为任何
- r - 如何通过删除列中的特定值来创建新数据框?
- javascript - 无法从 Node JS 中的另一个箭头函数调用箭头函数
- android - 手机上的 Unity 2D 滑动延迟
- opengl - 片段的 Opengl 相对 Z 缓冲区
- snowflake-cloud-data-platform - SnowSQL 安装 Ubuntu 16.04.6