maxmantz / redux-oidc

A package for managing OpenID Connect authentication in ReactJS / Redux apps
MIT License
400 stars 111 forks source link

User signs out in Chrome after a few seconds #52

Closed TomF-NVM closed 6 years ago

TomF-NVM commented 7 years ago

I'm using redux-oidc based on the usage example you provided. It is working fine in IE and Firefox. However, when I use it in Chrome:

I have tried both ^3.0.0-beta.3 and ^3.0.0-beta.7 and also tried both older and newer versions of react, redux etc.

In the console I see the following when I get de-authenticated: Action type: redux-oidc/USER_EXPIRING store.js:14 Action payload: undefined store.js:15 State before: Object {routing: Object, oidc: Object} store.js:17 State after: Object {routing: Object, oidc: Object} store.js:13 Action type: redux-oidc/SILENT_RENEW_ERROR store.js:14 Action payload: Error: Frame window timed out at t._error (oidc-client.min.js:74) at t._timeout (oidc-client.min.js:74)

Thanks

TomF-NVM commented 7 years ago

I found that setting monitorSession to false means Chrome stays logged in. "Will raise events for when user has performed a signout at the OP.". I don't know why this would be different for Chrome, or why it's occurring though.

maxmantz commented 7 years ago

I'm using chrome in my dev environment as well and I don't have these issues. It appears that something is wrong with the silent renew configuration. What is surprising is that your token lifetime seems to be very low. USER_EXPIRING is only dispatched when the token is about to expire. Does your token only have a 5 second lifetime?

EdwardSalter commented 7 years ago

I am also seeing the same issue in IE11 using version 3.0.0-beta.7. Firefox, Chrome, Opera and Edge all work as expected. The access token has an expiration of an hour but still executes the signout.

On a page refresh I get the redux-oidc/USER_FOUND action followed by my app kicking in and firing a bunch more actions and then a couple of seconds later, the redux-oidc/USER_SIGNED_OUT.

Like TFNVM, setting monitorSession: false fixes this problem. What are the implications of disabling this? If the user signs out of the OIDC system, the user will still be logged into my system?

After debugging a little more, it seems that IE is making a request to the connect/authorize endpoint with a redirect_uri pointing to my silent renew page almost immediately. Without knowing the inner workings of the OIDC system, I am assuming that this is the silent renew request? This request is only sent immediately in IE11 and in this case is returning an error page from the OIDC system (an internal SSO provider). The funny thing is that this request is sent in IE regardless of the automaticSilentRenew configuration setting. I have it set as false in my dev envrionment and it is still sent.

I guess I have 2 issues here (assuming that my assumption about the call to connect/authorize is correct):

  1. The silent renew is still happening in IE11, even when disabled.
  2. The OIDC system is returning an error which is something I will have to address with my OIDC provider.
maxmantz commented 6 years ago

Were you able to check your token lifetime to see whether or not this is too low? Usually, oidc-client automatically renews the token 5 minutes before expiration, which means that if the token lifetime is lower than that, it will enter an endless cycle of renewal.

EdwardSalter commented 6 years ago

By adding in an additional reducer that simply logs on redux-oidc/USER_FOUND I was able to see that the token has a lifetime of an hour as expected just like the other browsers report. I have just upgraded to 3.0.0-beta.13 and it still seems to be occurring. It is a particularly tricky one to debug since the redirect loop causes the dev tools to close after redirecting to the OIDC provider. Do you have any ideas on how I could debug this further? I will try updating my OIDC provider to see if that helps now.

maxmantz commented 6 years ago

There are a few things you could try:

Are you using the middleware? If so, consider replacing it with the loadUser helper like here. The middleware can be tricky to debug because of the interactions with the OIDC provider. If you have silent renewal set up, using loadUser instead of the middleware is the preferred way of doing things.

EdwardSalter commented 6 years ago

I am supposed to have silent_renew enabled for the production build but disabled in development (I cannot remember the reason why I did this) but IE adds the following iframe with the following src that the other browsers do not do. This suggests to me that silent_renew is still enabled in IE: http://redacted/identity/identity/connect/authorize?client_id=redacted&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fsilent_renew.html&response_type=id_token&scope=openid&state=bb7295efded84637b1af0fe49343aa6f&nonce=03f5a89107ce43a89522ac0b88e1459c&prompt=none

This is the config as taken from the IE dev tools.

   {
      authority: "http://redacted/identity/identity",
      automaticSilentRenew: false,
      client_id: "redacted",
      filterProtocolClaims: true,
      loadUserInfo: false,
      post_logout_redirect_uri: "http://localhost:3000/login",
      redirect_uri: "http://localhost:3000/callback",
      response_type: "id_token token",
      scope: "openid profile",
      silent_redirect_uri: "http://localhost:3000/silent_renew.html"
   }

I am indeed using loadUser over the middleware as I had issues with that when I set up the original code.

After adding the following reducer:

(state = null, action) => {
  if (action.type && action.type.startsWith('redux-oidc/')) {
    console.log(action.payload)
    debugger // eslint-disable-line
  }
  return state
},

I was able to determine that the following actions were called:

maxmantz commented 6 years ago

This is very strange indeed. With the current information I have honestly no idea what causes this. This seems to be a deeper issue with oidc-client. Please raise an issue there.

b5imply commented 4 years ago

Hello, I got this issue as well when using Chrome. I was able to fix this by disabling monitor session in user manager config (monitorSession: false). Was a bit a needle in the haystack moment when I just tested every setting possible. I hope this helps.