microsoft-authentication-library-for-js: MsalAuthenticationTemplate causes redirect loop when refresh token expires

Core Library

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

Core Library Version

2.28.0

Wrapper Library

MSAL React (@azure/msal-react)

Wrapper Library Version

1.4.4

Description

MsalAuthenticationTemplate seems to cause a redirect loop when a tab is left open long enough for the refresh token to expire.

Error Message

By looking at the network calls, i see this pattern; image

  • 2 token POST requests, which fails with this error
"AADSTS700084: The refresh token was issued to a single page app (SPA), and therefore has a fixed, limited lifetime of 1.00:00:00, which cannot be extended. It is now expired and a new sign in request must be sent by the SPA to the sign in page. The token was issued on 2022-08-08T07:07:56.0747046Z.\r\nTrace ID: b207e2d4-c9c3-4049-a4d5-3694ef474e00\r\nCorrelation ID: adfb57f2-e2ee-43fe-94a1-8945ea5b782e\r\nTimestamp: 2022-08-09 07:46:00Z"
  • A silent sign-in request is made (subdocument requests), which redirects back with this error
[#error=login_required&error_description=AADSTS50058%3a+A+silent+sign-in+request+was+sent+but+no+user+is+signed+in.%0d%0aTrace+ID%3a+0df1e86c-cba3-4506-8025-554c38d94400%0d%0aCorrelation+ID%3a+f1732dbf-804e-4f0a-808f-90fc490e8b85%0d%0aTimestamp%3a+2022-08-09+07%3a45%3a59Z&error_uri=https%3a%2f%2flogin.microsoftonline.com%2ferror%3fcode%3d50058&state=...#error=login_required&error_description=AADSTS50058%3a+A+silent+sign-in+request+was+sent+but+no+user+is+signed+in.%0d%0aTrace+ID%3a+0df1e86c-cba3-4506-8025-554c38d94400%0d%0aCorrelation+ID%3a+f1732dbf-804e-4f0a-808f-90fc490e8b85%0d%0aTimestamp%3a+2022-08-09+07%3a45%3a59Z&error_uri=https%3a%2f%2flogin.microsoftonline.com%2ferror%3fcode%3d50058&state=...
  • A full redirect is taking place, which actually seems to be successful, as I don’t get any errors, but then it starts again. I wonder if there might be some timing issues, and MsalAuthenticationTemplate is trying to fetch new tokens with the expired refresh token before the PublicClientApplication has finished its auth code flow

Msal Logs

No response

MSAL Configuration

const msal: Configuration = {
  auth: {
    clientId: 'CLIENT_ID',
    authority:
      'https://login.microsoftonline.com/TENANT_ID',
    redirectUri: window.location.origin,
    cloudDiscoveryMetadata:
      process.env.REACT_APP_CLOUD_DISCOVERY_METADATA ??
      'cloud_discovery_metadata',
    authorityMetadata:
      process.env.REACT_APP_AUTHORITY_METADATA ??
      'authority_metadata'
  }
}

Relevant Code Snippets

root.render(
  <React.StrictMode>
    <MsalProvider instance={instance}>
      <MsalAuthenticationTemplate
        interactionType={InteractionType.Redirect}
        authenticationRequest={{
          scopes: [
            'api://api_client_id/user_impersonation'
          ],
          extraScopesToConsent: ['User.Read']
        }}
      >
        {/* REST OF APP */}
      </MsalAuthenticationTemplate>
    </MsalProvider>
  </React.StrictMode>
)

Reproduction Steps

This is kind of hard, as it only happens after the refresh token has expired, so I have to wait a day. This process might be able to be sped up if you can configure the refreshtoken and accesstoken to expire faster.

Expected Behavior

Not looping.

Identity Provider

Azure AD / MSA

Browsers Affected (Select all that apply)

Firefox

Regression

No response

Source

External (Customer)

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 2
  • Comments: 21 (4 by maintainers)

Most upvoted comments

@h3rmanj Thanks for opening this issue,can you kindly please share the logs on my email found in Github profile?

I can’t seem to reproduce it

I’ve tried making a simple app, with forceRefresh: true so it tries to fetch an access token on every reload without it being expired. https://codesandbox.io/s/shy-pond-689hjt?file=/src/App.js

  1. Login to the site ( https://689hjt.csb.app/ )
  2. Run Revoke-AzureADSignedInUserAllRefreshToken PS command
  3. Reload site so it tries to fetch new access token and realizes the refresh token is invalid

It seems to run correctly then, so I wonder if it has any different behavior if the token is expired, rather than forced fetched.

Revoking refresh token manually also don’t cause the redirect loop in my original application, it only seems to happen if the tokens are expired.