We are using custom policies for user flow for our app. Every time when user completes the flow, they are redirected back to /setting page from where the policy was actually triggered. However, every time user is redirected after the flow, I get ServerError: invalid_grant: undefined - [undefined]: AADB2C90085: The service has encountered an internal error. Please reauthenticate and try again. Although we are catching the error that results in unexpected behavior for some other flows where we want to logout the user after they have completed the flow.
function b2cFactory(config: B2cConfig): IPublicClientApplication {
return new PublicClientApplication({
auth: {
clientId: config.clientId,
authority: config.authorities.signUpSignIn,
redirectUri: window.origin,
postLogoutRedirectUri: window.origin,
knownAuthorities: [config.authorityDomain]
},
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: false
},
system: {
loggerOptions: {
// eslint-disable-next-line ban/ban, no-console
loggerCallback: (level, message) => console.log(message),
logLevel: config.logLevel,
piiLoggingEnabled: false
}
}
});
}
And guard configuration
export function b2cGuardFactory(): MsalGuardConfiguration {
return {
interactionType: InteractionType.Redirect,
loginFailedRoute: `${window.origin}/error/B2C_USER_LOGIN_FAILED/1`
};
}
the b2c service in question
init() {
this.msalBroadcastService.msalSubject$.subscribe((event: EventMessage) => {
switch (event.eventType) {
case EventType.ACQUIRE_TOKEN_SUCCESS:
this._tokenSubject.next((event.payload as AuthenticationResult)?.accessToken);
break;
case EventType.HANDLE_REDIRECT_END:
this.checkAndSetActiveAccount();
break;
case EventType.SSO_SILENT_FAILURE:
// Sso session is expired but jwt can be still valid.
this._ssoSessionExpired = true;
break;
default:
if (event.error) {
if (event.error.message?.indexOf('AADB2C90091') > -1) {
this.window.location.replace('/settings');
} else {
console.error(event.error);
}
}
}
});
So when the following function is triggered, and user completes the flow and is redirected to app, the error block above catches the error and blocks the logout logic.
changeEmail() {
// Redirect the user to ProfileEdit policy
this.authService.loginRedirect({
extraQueryParameters: {
p: 'B2C_1A_PROFILEEDIT'
},
scopes: OIDC_DEFAULT_SCOPES,
}).subscribe(() => this.logout());
}