Skip to content

Fix: auto-retry OAuth2 flow on invalid state instead of showing error#8674

Open
addow wants to merge 1 commit into
chamilo:masterfrom
webstone:fix/oauth2-invalid-state-retry
Open

Fix: auto-retry OAuth2 flow on invalid state instead of showing error#8674
addow wants to merge 1 commit into
chamilo:masterfrom
webstone:fix/oauth2-invalid-state-retry

Conversation

@addow

@addow addow commented Jun 29, 2026

Copy link
Copy Markdown

Problem

When the OAuth2 state stored in the PHP session is lost between the
/connect/{provider} redirect and the /connect/{provider}/check
callback, the KnpU\OAuth2ClientBundle throws an
InvalidStateAuthenticationException. The user sees a confusing red
flash message — "Invalid state parameter passed in callback URL."
and is redirected to the home page, where they must manually navigate
back to the login page and click the SSO button again.

This can happen due to:

  • Session garbage-collection between the two requests
  • A stale Symfony cache that serialises session services incorrectly
  • Concurrent background requests competing for the session lock

The scenario we observed: admin logs in via SSO → uses "Login as" to
impersonate another user → logs out → tries to re-authenticate via SSO →
hits the invalid-state error because the session was invalidated during
logout and the new session state was lost.

Solution

Catch InvalidStateAuthenticationException in
AbstractAuthenticator::onAuthenticationFailure() and transparently
restart the auth flow by redirecting to the provider's start URL
(/connect/{provider}). A session flag (_oauth2_state_retry_{provider})
limits this to one automatic retry per provider; a second consecutive
failure still shows the error, preventing an infinite redirect loop.

The change is a one-file patch affecting all OAuth2 providers
(generic, Facebook, Keycloak, Azure) equally.

Test plan

  • Log in via SSO → works normally (no regression)
  • Simulate invalid state: open /connect/{provider}, clear the session cookie, follow the callback URL → should transparently retry and land on the login page (or complete auth), not show an error
  • Verify the retry flag prevents looping: if auth still fails on retry, the flash error appears as before

When the OAuth2 state cookie is lost between the redirect and callback
(e.g. due to session GC, concurrent requests, or cache/session mismatch),
the user gets a confusing "Invalid state parameter" error. Fix by
transparently restarting the auth flow on the first failure; a second
consecutive failure still shows the error to avoid infinite loops.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant