Replies: 3 comments
-
I am curious to know how you figured it out. I think that this is quite common behavior for the apps, since they rely on the state being saved in the cookie / state, which then gets overriden. |
Beta Was this translation helpful? Give feedback.
-
I supposed that this is a common behavior, and hoped it has already being addressed. The following mechanism may be applied to solve this problem: Every time the Auth Code flow starts, we must set a uniquely named copy of the session cookie.
As a result, when N tabs are started, there will be one "original" session cookie, plus N cookies with different names and session ID's opened at the time of each of N requests. We will call them "spare sessions" When the OAuth2 state check will fail, it should try to lookup spare sessions for a valid state. If valid spare session found, its cookie will be wiped. Then we can send user back to returnUrl found in this spare state, this time he will follow redirect with correct session cookie.
If no spare session found the flow will fall back to error as expected. The tab accessing the return URL will already bear the correct session cookie shared by all tabs. However, it may reach the target page or may start an Auth Code flow again, depending on the racing conditions of Auth in other tabs. If it comes too early, before any other tab has finished the authorization, then new Auth Code flow is started, and a new state with return_url is saved in a current session. On the way back from Azure to Auth callback URL, the session may already be authorized in another tab. In this case we must stop the flow, and redirect to the original return_url, which may be found in a current or a spare session.
At this point the spare session ID may be discarded, and its cookie unset. The tab will finally get the protected page, as all other tabs, sharing the same session cookie, as usual
Full code sample
Thanks... @hajekj , would you mind to review this proposal |
Beta Was this translation helpful? Give feedback.
-
I ran into a similar problem when I was writing the SendOauth2 wrapper** for PHPMailer. I even had an occasional and not repeatable ‘Invalid state’ with both Chrome and Edge when only ONE tab was open: the cookie key was set but the Session state returned from PHP server was null, which I put down to some unidentified race condition (a race with what else? - looked impossible!) ** decomplexity/SendOauth2 – see SendOauth2D.php |
Beta Was this translation helpful? Give feedback.
-
The nature of cookie based sessions and state parameter handling in OAuth2 Auth Code Flow expose a problem, when new browser session is started with multiple tabs trying to concurrently open several links on a "Secure Server" ( oauth2-azure client).
When the browser is started it discards all previous session cookies. Multiple tabs may be opened at once by the browser in case of crash recovery, or by the user, from bookmarks folder or history.
In such cases all tabs will simultaneously send unauthenticated requests to Secure Server. Each request will start a new session and a new Auth Code Flow, with new state param, that will be saved in this session.
All Secure Server's redirect-to-Identity-Provider responses will bear a session cookie with the same name, but a different value. They will overwrite each other in browser, and only the last one will be kept by browser as the Session ID.
Each tab will continue down the Authorization Code flow to Identity-Provider login page and back to Secure Server, bearing different state param, but same session cookie (set by the last tab).
Those state params were saved in now lost sessions and cannot be verified. State param validation failure is forbidden, and error 403 is issued.
The result is that all tabs except the last one end on 403 page.
Before I share my solution, I woulld like to find out if there any well known practices to solve this issue.
Thanks
Beta Was this translation helpful? Give feedback.
All reactions