Microsoft-authentication-library-for-js: Multiple concurrent RT renewals result in State mismatch error

Created on 20 Aug 2020  路  12Comments  路  Source: AzureAD/microsoft-authentication-library-for-js

Please follow the issue template below. Failure to do so will result in a delay in answering your question.

Library

Important: Please fill in your exact version number above, e.g. [email protected].

Framework

React

Description

Users get an exception "State mismatch error. Please check your network. Continued requests may cause cache overflow."

Error Message

"State mismatch error. Please check your network. Continued requests may cause cache overflow."

Security

  • [ ] Is this issue security related?

Regression

  • [ ] Did this behavior work before?
    Version:

MSAL Configuration

    const publicClientApp = new PublicClientApplication({
      auth: {
        clientId: this.clientId,
        authority: this.authority,
        redirectUri: this.loginRedirectUri,
        postLogoutRedirectUri: this.postLogoutRedirectUri
      },
      cache: {
        cacheLocation: "localStorage",
        storeAuthStateInCookie: isIEOrOldEdge // https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1188#issuecomment-634281307
      },
      system: {
        loadFrameTimeout: 30000,
        tokenRenewalOffsetSeconds: 60,
        loggerOptions: {
          loggerCallback: MsalAuthContext.msalLoggerCallback,
          piiLoggingEnabled: false,
          logLevel: LogLevel.Verbose
        }
      }
    });
    const handleRedirectPromise = publicClientApp
      .handleRedirectPromise()
      .then(response => {
        this.account = response ? response.account : this.getAccount();
        if (!this.account) {
          this.publicClientApp.loginRedirect({
            scopes: this.scopes,
            authority: this.authority
          });
        }
      })
      .catch(error => {
        if (error) {
          this.trackError(error);
        }
      });

Reproduction steps

  1. Make multiple acquireTokenSilent calls in parallel with different sets of scopes.
  2. When a new RT is needed, two requests to /authorize will be made.
  3. One of the requests will fail, as the temporary cache value will be overwritten.

Expected behavior

Browsers/Environment

these are the browsers we have observed so far with this error, may not be just these browsers

  • [X] Chrome
  • [ ] Firefox
  • [X] Edge
  • [ ] Safari
  • [ ] IE
  • [ ] Other (Please add browser name here)
bug msal-browser work-in-progress

Most helpful comment

@jasonnutter, @jmckennon, is there a timeline on 2.1.1 release? We had to revert back to using 1.x in our app due to this issue: proposed workaround (make token fetches serial) causes perf regression so we can't take it.

We'll work to have this fixed soon (by next week, hopefully).

All 12 comments

@thoo1 Can you confirm that this error happens when your app calls loginRedirect? What is the value of the redirect URI you are using?

@jasonnutter I'm not 100% sure if this is only when app calls loginRedirect, I'll add some more instrumentation to see if that's the case

The value of redirectUri: this.loginRedirectUri is the baseUrl for the app, which I've confirmed is added to the list of redirect uris, with type: "SPA"

I'll let you know once I know, if the error happens when user is trying to loginRedirect

@jasonnutter actually, I checked again, we log when we call acquireTokenSilent and can confirm from our logs, that these exceptions are occuring after we call acquireTokenSilent. There is another exception that seems to be thrown alongside this one

"Token acquisition in popup failed due to timeout."

Hope that helps and gives a hint to the problem maybe? Maybe I have to increase the timeout for the iframe?

@thoo1 Popup operations should rarely fail due to timeout, as timeouts likely caused by improper configuration.

By chance does your app support a www. subdomain (alongside a non-prefixed verison)? e.g domain.com and www.domain.com

nope, it doesnt support a www. subdomain

@jasonnutter for the point about popup operations, we dont call any of the popup interaction apis (only use silent and redirect interactions), in that case, what does the "Token acquisition in popup failed due to timeout." mean? Is it referring to the iframe as the popup?

@thoo1 Ah, yes the same error message is used for both, I'll make sure we update that. cc: @jmckennon

For both the timeout and state mismatch errors, any debugging you can do in your app would be helpful. What is happening inside the iframe (e.g. has it redirect back to your redirect URI with a hash, or is something else going on)? Why does MSAL think the state values do no match (e.g. do the state strings include special characters that are not decoded/encoded, is there a cache state value in local storage or not)?

Worked with @thoo1 to determine that this happens when multiple silent RT renewals happen in parallel, as the cached state value gets overwritten for one of the requests. Mitigation is make these requests in serial.

This issue has not seen activity in 14 days. It will be closed in 7 days if it remains stale.

@jasonnutter, @jmckennon, is there a timeline on 2.1.1 release? We had to revert back to using 1.x in our app due to this issue: proposed workaround (make token fetches serial) causes perf regression so we can't take it.

@jasonnutter, @jmckennon, is there a timeline on 2.1.1 release? We had to revert back to using 1.x in our app due to this issue: proposed workaround (make token fetches serial) causes perf regression so we can't take it.

We'll work to have this fixed soon (by next week, hopefully).

Was this page helpful?
0 / 5 - 0 ratings