microsoft-authentication-library-for-js: Can't find how to handle AADB2C90091 error code when redirected to a MSALGuard route

Core Library

MSAL.js v2 (@azure/msal-browser)

Core Library Version

2.31.0

Wrapper Library

MSAL Angular (@azure/msal-angular)

Wrapper Library Version

None

Public or Confidential Client?

Public

Description

When cancelling a workflow, like EditProfile, the redirect (back) to the app blows up when the route is MSAL guarded. No content renders as a result.

Error Message

main.js:213873

   ERROR ServerError: access_denied: AADB2C90091: The user has cancelled entering self-asserted information.

Correlation ID: 8cfece7a-4f8f-4532-91ea-93d51ab85d8b Timestamp: 2023-03-16 20:28:45Z

at ServerError.AuthError [as constructor] (main.js:20566:20)
at new ServerError (main.js:21755:24)
at ResponseHandler.validateServerAuthorizationCodeResponse (main.js:23285:13)
at AuthorizationCodeClient.handleFragmentResponse (main.js:18854:21)
at RedirectHandler.<anonymous> (main.js:12341:50)
at step (main.js:1551:17)
at Object.next (main.js:1482:14)
at main.js:1454:67
at new ZoneAwarePromise (polyfills.js:9455:21)
at __awaiter (main.js:1433:10)

Msal Logs

No response

MSAL Configuration

export function MSALInstanceFactory(): IPublicClientApplication {
	return new PublicClientApplication({
		auth: {
			clientId: environment.msalConfig.auth.clientId,
      		authority: environment.b2cPolicies.authorities.signIn.authority,
			redirectUri: window.location.origin,
			postLogoutRedirectUri: environment.msalConfig.auth.logoutRedirectUri, 
			knownAuthorities: [environment.b2cPolicies.authorityDomain]
		},
		cache: {
			cacheLocation: BrowserCacheLocation.SessionStorage,
			storeAuthStateInCookie: isIE, // set to true for IE 11.
		},
		system: {
			loggerOptions: {
				loggerCallback,
				logLevel: LogLevel.Verbose,
				piiLoggingEnabled: false
			},
		},
	});
}

Relevant Code Snippets

Call a policy from a guarded route

Reproduction Steps

Sign into the app. From MSAL-guarded route, trigger ViewProfile policy. On ViewProfile policy, click Exit. Returns to app, and guarded route, but nothing renders.

Expected Behavior

After cancelling a workflow, I should be able to go back to my application is if nothing happened.

Identity Provider

Azure AD / MSA

Browsers Affected (Select all that apply)

Chrome, Edge

Regression

No response

Source

External (Customer)

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Comments: 26 (8 by maintainers)

Most upvoted comments

@derisen I was able to confirm that your mitigation works w/ the sample app.

Thank you @derisen. I’m out of the office this week, on vacation. I wanted to let you know in the event that there’s inactivity on this work item.

@doug-williamson sorry for the delayed response. I can reproduce this. Looks like the Guard correctly loads the failed-component when this error occurs, but keeps navigating to the failed-component afterwards due to the cached handleRedirectPromise result from the previous request.

[Tue, 21 Mar 2023 01:28:41 GMT] : @azure/msal-angular@2.5.2 : Verbose - Guard - canActivate [Tue, 21 Mar 2023 01:28:41 GMT] : @azure/msal-angular@2.5.2 : Verbose - MSAL Guard activated [Tue, 21 Mar 2023 01:28:41 GMT] : @azure/msal-browser@2.32.2 : Verbose - handleRedirectPromise called [Tue, 21 Mar 2023 01:28:41 GMT] : @azure/msal-browser@2.32.2 : Verbose - getAllAccounts called [Tue, 21 Mar 2023 01:28:41 GMT] : @azure/msal-browser@2.32.2 : Verbose - handleRedirectPromise has been called previously, returning the result from the first call [Tue, 21 Mar 2023 01:28:41 GMT] : @azure/msal-angular@2.5.2 : Error - Guard - error while logging in, unable to activate main.js:390 [Tue, 21 Mar 2023 01:28:41 GMT] : @azure/msal-angular@2.5.2 : Verbose - Guard - loginFailedRoute set, redirecting

I need to debug further to identify the root cause and mitigate. For the moment you can workaround this by reloading the page or doing a URL navigation instead of with router, e.g:

    // in app.component.ts

    this.msalBroadcastService.msalSubject$
      .pipe(
        filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_FAILURE || msg.eventType === EventType.ACQUIRE_TOKEN_FAILURE),
        takeUntil(this._destroying$)
      )
      .subscribe(
        (result: EventMessage) => {
          if (result.error && result.error.message.indexOf('AADB2C90091') > -1) {
            window.location.reload(urlToNavigate)
          };
        },
      );

cc @jo-arroyo do you have any insights here?