Skip to content

Validating access_token failed. wrong state/nonce in Internet Explorer only. #390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ppozeti opened this issue Jul 31, 2018 · 11 comments
Closed

Comments

@ppozeti
Copy link

ppozeti commented Jul 31, 2018

Hi everyone,

I'm getting this error in Internet Explorer 11.
validating access_token failed. wrong state/nonce.

The scenario is the following:
I have setup like below:

    this.oauthService.tryLogin().then(() => {
      if (!this.oauthService.hasValidIdToken() || !this.oauthService.hasValidAccessToken()) {
        console.log('startSigninMainWindow URL', window.location.href)
        this.oauthService.initImplicitFlow(window.location.href);
      }
    });

When I'm not logged in and try to go to http://localhost:4200/somecrazyroute?abc=123. It checks that I'm not logged in, send me to the IdP with "http://localhost:4200/somecrazyroute?abc=123" in the state.
After logon, it correctly send me back to http://localhost:4200/somecrazyroute?abc=123.
Except in Internet Explorer 11!

I know the problem is when I have query parameters like ?abc=123. If I remove it, it works.

@ppozeti
Copy link
Author

ppozeti commented Jul 31, 2018

All right. I was able to reproduce the issue in the demo application of this repo.

To fix it, I removed the piece of code that appends the state into the nonce:

if (state) {
    state = nonce + this.config.nonceStateSeparator + state;
} else {
    state = nonce;
}

After research its clear that no one knows what can and can't be stored in the state property, but, I did find something really useful here: https://auth0.com/docs/protocols/oauth2/oauth-state#how-to-use-the-parameter-to-restore-state
So basically its the app responsibility to store its state and then once you get the authentication you can redirect your user to the saved state.

I do understand for us, library consumers, having this option embedded in this library is much better than handling it by ourselves.
So to keep that as an option, I will submit the changes I did as a PR and we can discuss if its a valid option or not.

@ppozeti ppozeti closed this as completed Jul 31, 2018
@jeroenheijmans
Copy link
Collaborator

Perhaps what you reference is documented here? (Though I think it's recommended to handle event subscription slightly differently in newer versions.)

@ppozeti
Copy link
Author

ppozeti commented Jul 31, 2018

@jeroenheijmans , the code works fine in chrome. I get redirected to IdP, log in, come back to auth.html, then it redirects me to the "state" page.
But, it doesn't work the same with IE. To reproduce that, just run the demo app with the following on ngOnInit:

  ngOnInit() {
    this.oauthService.tryLogin().then(() => {
      if (!this.oauthService.hasValidIdToken() || !this.oauthService.hasValidAccessToken()) {
        this.oauthService.initImplicitFlow(window.location.href);
      }
    });
  }

Then access your page using IE 11 like http://localhost:8080/home?test=123
You should get the same error I got in the beginning.

The PR I want to submit is to think on another way to persist that "state" url... Because looks like we shouldn't keep that along with the state (nonce).

@danielwegener
Copy link

danielwegener commented Aug 24, 2018

Well, this PR (#391) changes the behaviour how additionalState works across tabs (you are using local storage), and in fact it would break our integration, so 👎 (maybe rather use the configured storageProvider?).

The fix for your problem would be to simply encode your state into something url safe before you pass it as a parameter to initImplicitFlow (e.g. base64url). In fact, the encoding should be done in angular-oauth2-oidc, but for some reason as you describe it does not work in the IE. This is the problem that should be fixed!

According to the spec, state is exactly there to prevent csrf and encode state to rebuild the application. What you have built, is something that has nothing todo with OIDC and should IMO not be part of this lib (especially because it is labeled unter the well known oauth2-concept (additional-)"state-parameter").

@JohannesHoppe
Copy link

I have to confirm that this error still does exist in IE11. Does anybody have a solution for this?
It works flawlessly in Chrome... 😞

image

@JohannesHoppe
Copy link

I'll answer my question myself, maybe it'll help someone.

  1. This is all related to the fact, that all content of the storage gets lost.
  1. With IE11 (v11.1324.15063.0 © 2015) on Windows 10 it's enough to change the the OAuthStorage to localStorage - as seen here sendAccessToken sends null token when using local storage #255 (comment)
  2. With IE11 (v11.0.9600.19155 © 2013) on Windows 7 this didn't helped. I had to completely deactivate the check against the nonce:
this.oauthService.loadDiscoveryDocumentAndLogin({
  disableOAuth2StateCheck: true
})

This workaround is far from perfect, but now the access token is always available.

@ppozeti This issue is not solved, could you open it again?

@JohannesHoppe
Copy link

Hello everybody, we tracked the issue down to this bug in Internet Explorer:
https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/110656/
The bug was fixed in later versions of IE11.

Solutions:

  • Update that IE 11 to the latest version of Internet Explorer 11! If necessary, escalate that critical issue to your big boss and tell him that your infrastructure team is doing a unbelievable bad job by letting you use rotten software
  • if that doesn't help 😉:
    • put your angular app and also your issuer to THE SAME zone. The bug happens because you change zones during the redirect which lets IE forget everything (until reload). It is possible to change the zone of websites via a Group Policy!

see this:

image

FYI @manfredsteyer

@gawadesantosh14
Copy link

Hi All, I`ve also faced the same issue few days back in IE browser that when IE browser performs redirection from application URL to ADFS URL then it clears out local-storage so whenever the flow comes back to application after authentication at that time the claimed nonce is not matching with local-storage nonce and then as a result of this it gives an error as 'invalid nonce'. We spend almost 1 week on this and finally as a workaround for this issue, added one method which again set nonce in local-storage from the redirection URL in case of IE browser.

@JohannesHoppe
Copy link

JohannesHoppe commented Mar 20, 2019

Best solution: Update that shitty IE 11 to the latest version of Internet Explorer 11! If necessary, escalate that critical issue to your big boss and tell him that your infrastructure team is doing a unbelievable bad job by letting you use rotten software! 😉

@CedricHg
Copy link

What if you're in my situation and are trying to use this on a public-facing site, where you can't control what version of IE11 your customers are using?

@JohannesHoppe
Copy link

The IE11 error mentioned here only occurs in an intranet. In the Internet, all websites have the same zone.

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

No branches or pull requests

6 participants