Мы используем MSAL.js для аутентификации пользователей в нашем экземпляре Azure AD B2C. Пользователи могут использовать локальную учетную запись или войти, используя свои учетные данные из другого экземпляра Azure Active Directory.
После входа в систему наш SPA получает токен доступа с использованием acquTokenSilent с резервным откликом на acquTokenPopup.
Что мы заметили, так это то, что по истечении времени срока действия acquTokenSilent токен может по-прежнему извлекаться в фоновом режиме, а локальное хранилище приложения обновляется токеном. Однако в приложении мы перешли к вызову acquTokenPopup. После того, как пользователь вводит свои учетные данные в acquTokenPopup, во всплывающем окне отображается «Плохой запрос». Пользователь может закрыть всплывающее окно, и если они обновят приложение, они теперь войдут в систему.
Этот опыт не очень удобен для наших пользователей.
Просто интересно, это известная проблема или ожидаемое поведение?
Вот соответствующая выдержка из нашего кода. Мы обертываем 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));
});
});
}