2.8 KiB
| title | connects | sources | created | updated | ||||
|---|---|---|---|---|---|---|---|---|
| Connection: OAuth State Mismatch — LibreChat vs MSAL SPA |
|
|
2026-04-15 | 2026-04-15 |
Connection: OAuth State Mismatch — LibreChat vs MSAL SPA
The Connection
Both LibreChat's built-in OpenID integration and custom MSAL.js SPA implementations use Azure AD OAuth with state validation. OAuth state mismatch — where the state parameter returned by Azure doesn't match what's in the session — manifests very differently in each system but has the same root causes.
Key Insight
In LibreChat, a state mismatch surfaces as Unknown OAuth error (the session message array is empty). In a custom MSAL.js SPA, a state mismatch surfaces as a silent redirect to an error page or a blank callback. In both cases, the fix is at the session layer (clear stale cookies, try a different browser), not in Azure AD configuration. This is non-obvious because the error points away from the actual cause.
The shared root cause: if the server restarts between OAuth initiation (/oauth/openid) and the callback (/oauth/callback), the session store loses the original state. Azure sends back the correct state, but the server-side session no longer has it to compare against — the check fails.
Evidence
- LibreChat (2026-04-15): User
santhosha.nayak@brandtech.pluscould not log in. Microsoft auth succeeded (user saw Microsoft login, approved it). LibreChat showedUnknown OAuth error. Network tab showed:302 → /oauth/openid → Microsoft OK → /oauth/callback → /oauth/error. Root cause: stale session cookie from a previous attempt after server restart. Resolution path: try different browser / clear cookies. - MSAL SPA (2026-04-15): MSAL.js v5 UMD in a plain-HTML dashboard. MSAL handles state internally via
sessionStorage. IfsessionStorageis cleared between initiation and callback (e.g., navigation, redirect loops), MSAL throws a state mismatch error client-side. MSAL's internal handling is more transparent than LibreChat's.
Diagnostic Heuristic
When OAuth fails after Microsoft auth succeeds:
- Check if this is a first attempt or a retry — retries are more likely to hit state mismatch
- Check if the server recently restarted
- Try from a different browser / incognito window
- Only then investigate Azure AD app registration, Conditional Access, or account status
Related Concepts
- wiki/concepts/librechat-openid-auth — LibreChat-specific auth internals and ALLOW_SOCIAL_REGISTRATION
- wiki/concepts/msal-vanilla-js-pkce — MSAL.js v5 UMD SPA implementation
- wiki/tech-patterns/azure-ad-msal-auth — Azure AD patterns across Oliver projects