okta / okta-auth-js

The official js wrapper around Okta's auth API
Other
453 stars 265 forks source link

[v4] signOut: Error Code: id_token_does_not_match_session #575

Open lfurzewaddock opened 3 years ago

lfurzewaddock commented 3 years ago

As recommended in related issue https://github.com/okta/okta-auth-js/issues/571 we have been testing the 'Refresh token rotation' early access feature, to support our use case: multiple Okta account simultaneous sign-in (one user account per web browser tab).

Early indications look promising. However, we have encountered an issue when signing out under certain circumstances: setup a SPA app using refresh tokens for auto-renewal rather than cookies. On the 1st web browser tab, sign-in to account "one" and on the 2nd web browser tab, sign-in to account "two". Then immediately, on the 1st web browser tab, sign-out and the error below will be raised. NB. expiry time for access tokens has been reduced to 5 mins via Okta admin UI.

Error;

image

I can see the lib signOut function is generating the url below: (some characters removed)

https://dev-000000.okta.com/oauth2/default/v1/logout?id_token_hint=eyJra__REMOVED__.eyJzdWIiOiIwMH__REMOVED__.QYRiR_zUoF_telfYAI97___REMOVED__&post_logout_redirect_uri=http%3A%2F%2Flocalhost%3A8040%2F

Can you confirm how the query param id_token_hint is constructed? Perhaps we can construct this url ourselves instead of using the lib calling;

oktaAuth.signOut({
      postLogoutRedirectUri: `${window.location.origin}/`,
      accessToken: authState.accessToken,
    }); // NB. 'postLogoutRedirectUri' must be an absolute URL

APP CONFIG/ENVIRONMENT

early access feature enabled: Refresh token rotation

  const oktaAuth = new OktaAuth({
    issuer,
    clientId,
    redirectUri,
    pkce,
    scopes, // -> ['openid', 'profile', 'email', 'offline_access']
    disableHttpsCheck,
    tokenManager: {
      autoRenew: true,
      secure: true,
      storage: 'sessionStorage',
      expireEarlySeconds: 120,
      cookies: {
        secure: true,
        sameSite: 'none',
      },
    },
  });

lib versions:

"@okta/okta-auth-js": "^4.5.0",
"@okta/okta-react": "^4.1.0",
swiftone commented 3 years ago

@lfurzewaddock -

First, thanks for the feedback. We're excited for this feature and reports from the field are invaluable.

Second, to cover your last question, the id_token_hint is just the URIEncoded id token (https://github.com/okta/okta-auth-js/blob/master/lib/browser/browser.ts#L385-L386 )

Third, to cover the general issue - this looks like some wires are getting crossed between the browser sessions. My instinct is to think it is the okta session cookie, because that is a cookie and not sessionStorage, but I'll need to recreate this situation and do some digging before that is anything more than speculation.

let me get back to you on this.

lfurzewaddock commented 3 years ago

Thanks for your quick response @swiftone.

I had thought the id_token_hint is just the URI Encoded id token, and had tried to identify it in both tabs, but could not, which I suppose is what the error is reporting. Now that I know it should match the current ID token, I will check again.

Yes, I agree it's probably related to the 'shared' session cookie, which was the cause of our original issue. I should also add that every 5 mins the tokens are renewed, which I would expect. However, the ID token is also renewed every 5 mins. I didn't expect this to change from 1 hour.

Lastly, if the tab for which I triggered the sign-out happens to be the last to have auto-renewed it's tokens, sign out behaves as expected without error.

I have created a personal/private Okta account for these tests so could you give you access to that if it helps.

lfurzewaddock commented 3 years ago

Sorry to bother you @swiftone, did you manage to recreate the issue?

artfuldev commented 3 years ago

Sorry to bother you @swiftone, did you manage to recreate the issue?

Hey @lfurzewaddock we are facing a similar issue - were you able to get to a resolution? cc @swiftone

TobyLi96 commented 2 years ago

Hello @lfurzewaddock @swiftone, we are facing a similar issue, wondering if you managed to find a fix?

artfuldev commented 2 years ago

The error occurred for us because we were trying to use 2 different sessions in 2 different apps but using the same auth server in a multi-tenant scenario. Every time the OKTA auth server authorizes a user, the auth server sets a session id cookie in its domain. When a user logs in with a new set of credentials then tries to log out of the old set of credentials, the client code picks up the identity token which no longer applies to the new session id that exists in the okta auth server cookie and that was the issue. We resolved this by changing our implementation. Hope it helps.

TobyLi96 commented 2 years ago

The error occurred for us because we were trying to use 2 different sessions in 2 different apps but using the same auth server in a multi-tenant scenario. Every time the OKTA auth server authorizes a user, the auth server sets a session id cookie in its domain. When a user logs in with a new set of credentials then tries to log out of the old set of credentials, the client code picks up the identity token which no longer applies to the new session id that exists in the okta auth server cookie and that was the issue. We resolved this by changing our implementation. Hope it helps.

Hmm, thank you for the reply. From what you said, it seems that having another auth server for the second app would solve the issue? Or do you mean changing something in your own code when you said "changing our implementation"?

artfuldev commented 2 years ago

@TobyLi96 We changed our implementation in a different way - but yes, having different auth servers for the different apps would solve the issue.

johnschlee commented 2 years ago

The error occurred for us because we were trying to use 2 different sessions in 2 different apps but using the same auth server in a multi-tenant scenario. Every time the OKTA auth server authorizes a user, the auth server sets a session id cookie in its domain. When a user logs in with a new set of credentials then tries to log out of the old set of credentials, the client code picks up the identity token which no longer applies to the new session id that exists in the okta auth server cookie and that was the issue. We resolved this by changing our implementation. Hope it helps.

@artfuldev - you mentioned above that you were able to resolve your issue by changing your implementation. Is there anything you can share about what you did?

srkumarp commented 1 year ago

Hi @artfuldev, I'm also facing the same issue, could you please tell me how you resolved it?

jaredperreault-okta commented 1 year ago

@johnschlee @srkumarp are you experiencing this issue with the versions list above or with current versions of authjs?

srkumarp commented 1 year ago

Hi @jaredperreault-okta,

Here are the dependencies "@okta/okta-angular": "^6.0.0", "@okta/okta-auth-js": "^7.0.1"

These are the issues I'm facing:

1) I have two user accounts. if I use "1st" account to sign-in to the angular app (first browser tab) and "2nd" account to sign-in to the Okta dashboard (second browser tab) and then if I try to sign out the 1st account from angular app (1st tab), I'm getting this error page.

image

I'm only getting this error when I use oktaAuth.signOut() to sign the user out of the SPA, but it's not happening when I have these two methods in my sign out function oktaAuth.revokeAccessToken(); this.oktaAuth.closeSession(); instead of oktaAuth.signOut().

2) I have two user accounts: "1st" account has a permission to log in to the SPA app, but "2nd" account doesn't have that permission. If I sign-in "2nd" account to the okta dashboard (browser tab1) and then in tab2, if I open up that SPA app to login "1st" account, okta automatically picks the previously logged-in user details ("2nd" account credentials instead of "1st" account) for sign-in and in "login/callback" it is getting struck and its throwing "OAuthError: User is not assigned to the client application." Error. is there any way I can fix this or always force the user to login?

Could you please tell me how I can fix these issues? I'm new to okta, please correct me if I misunderstood anything. FYI I'm currently using the dev okta account.