Angular-auth-oidc-client: Silent Renew - incorrect state while using back/forward button

Created on 12 Jun 2020  ·  8Comments  ·  Source: damienbod/angular-auth-oidc-client

Silent Renew mechanism breaks when back/forward browser buttons are used. Navigating back loads silent-renew.html with old authorization code and breaks authorization flow.

I used a code-flow-auto-login example with Keycloak as my identity provider. For faster-reproducing steps, I set Access Token Lifespan to 1 min.

Steps to reproduce the behavior:

  1. Visit app main page
  2. Log in
  3. Wait on the main page (/home) for the first silent renew call.
  4. Go to /forbidden page
  5. Wait until silent renew call happens
  6. Click back button

Browser console produces the following error:
image

Expected behavior
When using back/forward buttons (or programmatic history navigation) silent-renew.html should not dispatch oidc-silent-renew-message with old code.

  • OS: Ubuntu 18.04
  • Chrome Version 83.0.4103.61 (Official Build) (64-bit), Firefox 77.0.1 (64-bit)

image

In the above screen, there are 3 calls to silent-renew.html. The first one happened on the /home route, second on /forbidden route and the third one happens immediately after clicking the back button. You can see on the screen that query param for that call has an old code value (from the /home first call). After that, isAuthorize state is lost and the user is no longer logged in. Doing the same thing using links works fine.

I think that https://github.com/damienbod/angular-auth-oidc-client/issues/608 was the result of the same bug, but the conversation sidetracked a little bit and the main reason was not discovered.

investigate

Most helpful comment

I am having a similar issue, is there going to be any follow ups regarding this ? @GabrielGil I read through 788 and from what i can see I don't think it would be related to that.

  1. When we do the flow in our project... We have a landing page that triggers the authorization then we have a redirect page that is the page the Authorization server redirects back to with the code.
  2. this page triggers the checkAuth function (or in the old version of the app it didnt do anything i have a service that gets spun up that sets up the doCallbackLogicIfRequired() which i guess listens to the url parameter changes)
  3. In either case I think the clicking the back button changes the url back to the url that was sent back from the server which contains the state and code in the url from your original login request and the page refresh causes the checkAuth or in the older version doCallbackLogicIfRequired() to get triggered again against the stale values in the url.
  4. At the point in when it gets triggered there is a function to validate the state.. but the sessionState is empty by that point and that triggers the error to occur.

The only weird part is that if try to click the back button right away or only after 1 silentrefresh the error doesn't seem to happen.. it seems like a few refreshes have to go by before the error will happen.

This still occurs with version 11.2.0 of the library.

Below is what prints out in the console.. it seems like local state is empty in this case as i explained.

ValidateStateFromHashCallback failed, state: 15983741488470.88591959971311090.6089870809461122 local_state:
angular-auth-oidc-client.js:332

authorizedCallback incorrect state

All 8 comments

I think I'm hitting this problem as well, in an implicit flow in my case. I can only trigger the problem if 2 or more silent renews have passed without navigating; subsequently calling location.back() will return an authorizedCallback incorrect nonce error.

I've tried setting the ignoreNonceAfterRefresh to true, but that seems to only apply to the code flow? Result is the same..

@FabianGosebrink @damienbod If you need more information from me about the issue just let me know. I am pretty sure this happens every time if you follow the described steps.

Maybe this is related to #788.

I am having a similar issue, is there going to be any follow ups regarding this ? @GabrielGil I read through 788 and from what i can see I don't think it would be related to that.

  1. When we do the flow in our project... We have a landing page that triggers the authorization then we have a redirect page that is the page the Authorization server redirects back to with the code.
  2. this page triggers the checkAuth function (or in the old version of the app it didnt do anything i have a service that gets spun up that sets up the doCallbackLogicIfRequired() which i guess listens to the url parameter changes)
  3. In either case I think the clicking the back button changes the url back to the url that was sent back from the server which contains the state and code in the url from your original login request and the page refresh causes the checkAuth or in the older version doCallbackLogicIfRequired() to get triggered again against the stale values in the url.
  4. At the point in when it gets triggered there is a function to validate the state.. but the sessionState is empty by that point and that triggers the error to occur.

The only weird part is that if try to click the back button right away or only after 1 silentrefresh the error doesn't seem to happen.. it seems like a few refreshes have to go by before the error will happen.

This still occurs with version 11.2.0 of the library.

Below is what prints out in the console.. it seems like local state is empty in this case as i explained.

ValidateStateFromHashCallback failed, state: 15983741488470.88591959971311090.6089870809461122 local_state:
angular-auth-oidc-client.js:332

authorizedCallback incorrect state

We had the same issue, but we found a workaround for now.
See issue #877

Hello,
Our team also faced with the same issue. After some investigation we have found the same root cause of the problem as @DieterDS1983.

I wouldn't like to use the proposed workaround and I decided to fix it. Fortunately it's pretty simple to do, we need to change only one line:
from
https://github.com/damienbod/angular-auth-oidc-client/blob/916df15bfddeaca579adca74f67f4553b919b045/projects/angular-auth-oidc-client/src/lib/iframe/refresh-session-iframe.service.ts#L39
to
sessionIframe.contentWindow.location.replace(url);

Updating the “src” attribute causes the browser history to be updated, so instead we can use contentWindow.location.replace (it doesn't have such behaviour).

I've done this fix and have tested it locally in our development environment with different domains. Unfortunetly I can't create the PR:
remote: Permission to damienbod/angular-auth-oidc-client.git denied to Expelz. fatal: unable to access 'https://github.com/damienbod/angular-auth-oidc-client.git/': The requested URL returned error: 403

@damienbod Please check this solution and consider to include it into the next minor release ("version": "11.2.3").

Hey @Expelz , did you fork the project, create a new branch, committed and then tried to create the pr? Thanks, Fabian

@FabianGosebrink, Thanks! That was my mistake.
I 've created the PR #895 with this fix.

Was this page helpful?
0 / 5 - 0 ratings