Summary
This incident analyzes why an Angular 21 application using MSAL v4 forces users to re‑authenticate after closing all browser tabs and relaunching the browser, even though BrowserCacheLocation.LocalStorage is configured. The behavior surprises many engineers because it looks like a persistence failure, but the real cause is deeper inside MSAL’s token model.
Root Cause
The root cause is not Angular, MSAL configuration, or localStorage.
The real issue is:
- MSAL never persists refresh tokens in the browser (by design for security).
- PublicClientApplication (SPA) apps rely on hidden iframe silent refresh, which requires:
- A valid session cookie at the Microsoft identity endpoint
- A running browser context to execute the iframe
- When all browser windows close, the Microsoft session cookie is often cleared by:
- Browser privacy settings
- Edge/Chrome “Clear on exit”
- Third‑party cookie blocking
- Incognito mode
- Without that cookie, MSAL cannot silently refresh tokens, even if access tokens are in localStorage.
LocalStorage only stores access tokens, not the server-side session required for silent SSO.
Why This Happens in Real Systems
Real-world browsers behave inconsistently with identity cookies:
- Chrome/Edge treat identity cookies as third‑party cookies inside iframes.
- Many users have “Block third‑party cookies” enabled by default.
- Some corporate environments enforce session-only cookies.
- Closing all browser windows triggers cookie eviction, even if localStorage survives.
This means MSAL’s silent refresh mechanism fails, forcing a full login.
Real-World Impact
Teams commonly observe:
- Unexpected login prompts after browser restart
- Broken “remember me” expectations from users
- Confusion because localStorage appears intact
- Inconsistent behavior across browsers and machines
This leads to support tickets, user frustration, and incorrect assumptions that MSAL is misconfigured.
Example or Code (if necessary and relevant)
Below is the correct MSAL configuration for persistent caching, but it still cannot override browser cookie policies:
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: false
}
This is valid, but not sufficient to guarantee silent SSO after browser restart.
How Senior Engineers Fix It
Experienced engineers know this is a browser + identity platform limitation, not a code bug. They typically solve it using one of these strategies:
1. Enable “Keep Me Signed In” (KMSI)
- Configure Azure AD / Entra ID policies to allow persistent sessions.
- Ensures Microsoft identity cookies survive browser restarts.
2. Use Redirect Interaction Instead of Popup
- Redirect flows behave more reliably with identity cookies.
- Popup + iframe + third‑party cookie restrictions is a fragile combination.
3. Enable allowRedirectInIframe (if applicable)
- Helps in environments where iframes are blocked.
4. Switch to MSAL v3’s loginHint or sid claims
- Allows silent login using known user identity.
5. Use a Backend-for-Frontend (BFF)
- The most robust enterprise solution.
- Tokens stored server-side, not in the browser.
- Browser restart does not affect authentication state.
6. Educate users about browser privacy settings
- Especially third‑party cookie blocking.
Why Juniors Miss It
Junior engineers often assume:
-
LocalStorage = persistent login
(It does not. Tokens expire and cannot be silently refreshed without cookies.) -
MSAL controls cookie behavior
(It does not. Browsers and identity providers do.) -
Silent SSO works like a refresh token
(SPAs do not get refresh tokens.) -
Closing tabs should not affect authentication
(It does, because session cookies are browser-context dependent.)
They focus on MSAL configuration, while the real issue lies in browser identity cookie lifecycle, which is not obvious until you’ve debugged authentication flows across multiple browsers.
If you’d like, I can walk you through how to verify whether your browser is deleting the Microsoft identity cookies on exit.