A cloud-based identity and access management service for securing user authentication and resource access
The silent refresh issue
Client env as ms entra sso, the scope visible in browser
Microsoft Security | Microsoft Entra | Microsoft Entra ID
-
Shubham Sharma • 17,930 Reputation points • Microsoft External Staff • Moderator
2026-02-25T11:41:13.8766667+00:00 Thank you for reaching out to Microsoft Q&A.
Could you please provide the error details along with a screenshot of the issue you are encountering? This information will help us analyze the problem more effectively and assist you further.
-
Shweta Salaria • 0 Reputation points
2026-02-25T11:56:18.37+00:00 The details of error:
we have an application: one with keyclock sso— where once the session is about to expire we get token/ calls before that with grant_type=refresh token
and once the last token/ call fails we get redirected to auth page (expected behaviour)
but the same app with entra sso: we are only seeing initial /token call after login but before expiry no such behavior as keyclock and we sits on the same page no redirect to auth , all apis starts giving 401
we requested the entra team to add offline_access , they added it.
But still we are facing same issue
in first token response with entra we are sessing access token, id token , opaque refresh token , scope and all.
-
Shweta Salaria • 0 Reputation points
2026-02-26T13:57:36.7966667+00:00 For the offline_access to work for silent refresh , does it need admin consent?
-
Shubham Sharma • 17,930 Reputation points • Microsoft External Staff • Moderator
2026-02-27T12:27:44.12+00:00 Hello Shweta
Thank you for the reply.
I am checking with the internal team and get back to you shortly.
-
Shweta Salaria • 0 Reputation points
2026-03-01T19:51:05.44+00:00 To update you, the entra team has added offline_access in there scope, but the issue didn't resolve, Is it that it requires admin access?
or is it something with our ui angular code?
in our code silent refresh is configured, library being used is angular-oauth2-oidc
-
Shubham Sharma • 17,930 Reputation points • Microsoft External Staff • Moderator
2026-03-03T02:27:09.2133333+00:00 Hello Shweta Salaria
Thank you for your reply
You are seeing expected Microsoft Entra ID behavior, but it differs fundamentally from Keycloak. The issue is not that
offline_accessis missing; it’s that Entra does not proactively refresh tokens or auto‑redirect the browser the way Keycloak does. The application must explicitly request silent renewal and handle failure.- Why Keycloak and Entra behave differently (root cause)
Keycloak
Issues long‑lived refresh tokens
Client apps commonly run background refresh loops
When refresh finally fails → IdP redirects automatically
Refresh tokens are directly usable by the client
Microsoft Entra ID (Azure AD)
Uses MSAL-managed refresh tokens
No background refresh happens automatically
No redirect occurs unless your app explicitly triggers it
Refresh tokens for SPAs are:
Opaque
24‑hour fixed lifetime
Not directly usable by your code
Rotated internally by MSAL
Microsoft Entra expects the application to drive token renewal and redirection — not the identity provider.
Microsoft doc: https://learn.microsoft.com/entra/identity-platform/refresh-tokens
- Why offline_access did NOT fix the issue
What offline_access does:
Allows Entra to issue a refresh token
What it does NOT do:
Auto-refresh access tokens
Auto-redirect users on expiration
Trigger /token calls automatically
Even with offline_access, MSAL only refreshes tokens when acquireTokenSilent() is called.
Doc:
- Acquire a token to call a web API (SPA)
- https://learn.microsoft.com/en-us/entra/identity-platform/scenario-spa-acquire-token?tabs=react
- Why you see 401s and no redirect
Your current flow:
Login → initial /token call
Access token expires
App keeps calling APIs with expired token
APIs return 401
No redirect happens
Why?
Entra never pushes redirects
MSAL was never invoked to renew tokens
The browser remains on the same page indefinitely
Microsoft explicitly states that apps must catch token failures and initiate interactive login.
Doc:
Token expiration and revocation
https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens
Below are the resolution steps:-
- Call
acquireTokenSilent()before every API call - Handle failure (
InteractionRequiredAuthError) - Redirect or popup to login when silent refresh fails
SPA flow example:-
try {const token = await msalInstance.acquireTokenSilent({scopes: ["api://<client-id>/scope"],account: msalInstance.getActiveAccount()});callApi(token.accessToken);} catch (e) {if (e instanceof InteractionRequiredAuthError) {msalInstance.acquireTokenRedirect({scopes: ["api://<client-id>/scope"]});}}Doc:
- Managing token lifetimes and renewal (MSAL JS)
- https://learn.microsoft.com/en-us/entra/msal/javascript/browser/token-lifetimes
Microsoft Entra:
- Does not implement Keycloak-style refresh loops
- Does not auto-renew tokens in the background
- Only renews tokens when MSAL is explicitly called
This is a deliberate security design, especially for SPAs, due to:
- Browser privacy controls
- Third‑party cookie blocking
- Refresh token theft risks
Doc:
- Silent token acquisition behavior
- https://learn.microsoft.com/en-us/entra/identity-platform/scenario-spa-acquire-token?tabs=react
Why refresh tokens appear “opaque”
This is expected.
Microsoft states:
Refresh tokens are encrypted and unreadable
Only MSAL can use them
Apps must never parse or store them manually
Doc:
Refresh tokens are encrypted and only Microsoft identity platform can read them
https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens
-
Shubham Sharma • 17,930 Reputation points • Microsoft External Staff • Moderator
2026-03-06T09:15:22.97+00:00 Hello Shweta
Following up to check if the resolution provided above was helpful. Please let us know if you need any further assistance.
Sign in to comment