Skip to content
This repository has been archived by the owner on Mar 3, 2022. It is now read-only.

Error when authorize response is missing expires_in response parameter #534

Closed
bakedog417 opened this issue Apr 24, 2018 · 12 comments
Closed
Labels
Milestone

Comments

@bakedog417
Copy link

I'm getting a strange issue where upon receiving my id_token and access_token, I get the following log messages:

access token present, remaining duration: undefined
oidc-client.min.js?93dc:1 registering expired timer in: NaN
oidc-client.min.js?93dc:1 Timer.init timer Access token expired for duration: NaN
...
Timer._callback; Access token expired timer expires in: NaN
3oidc-client.min.js?93dc:1 unchanged message from check session op iframe

This effectively prevents any refreshing of the tokens from my IdP. (Which is still Keycloak)

As far as I can track it down, here is where it is trying to get the "expires_in" parameter from the url? According to the OIDC docs, "expires_in" should be an OPTIONAL param. Would it make more sense to harvest that value directly from the access_token?

Or did I miss something extremely obvious again?
Thank you

@brockallen
Copy link
Member

As far as I can track it down, here is where it is trying to get the "expires_in" parameter from the url? According to the OIDC docs, "expires_in" should be an OPTIONAL param. Would it make more sense to harvest that value directly from the access_token?

It's really OAuth2's expires_in that we care about, since it's the access token we're talking about. And yes, it's only marked as recommended. https://tools.ietf.org/html/rfc6749#section-4.2.2

So if the token server doesn't supply it, your client is SOL. Get a better token server :)

Would it make more sense to harvest that value directly from the access_token?

No, as access tokens are opaque to the client.

@brockallen brockallen added the bug label Apr 26, 2018
@brockallen
Copy link
Member

brockallen commented Apr 26, 2018

I'll mark this as a bug to deal with the absent expires_in, which means the client can't proactively know when to renew the access token.

@bakedog417
Copy link
Author

That make sense, I didn't realize the access_token should be otherwise ignored on the client except when thrown in a header.

This only came up when I switched to using SAML as the IdP for my IdP, which supplies 2 tokens only in the return URL.

Thanks for checking in on it.

@brockallen
Copy link
Member

I'll reopen this -- again, I think there's a bug in the sense that the code expects an expires_in.

@brockallen brockallen reopened this Apr 26, 2018
@bakedog417
Copy link
Author

Alright, so in the interim, any danger in doing something like this, provided my tokens expire >900s?

//TODO remove hack when lib gets updated
let hack = '&expires_in=900';

this.mgr.signinPopupCallback(window.location.href + hack).then((response) => {...

PS; sorry for closing the ticket, browser only showed your first response when I closed it.

@brockallen
Copy link
Member

yea, i guess hacking it for now might work. try it and let me know :)

@bakedog417
Copy link
Author

It certainly seems to kill the NaN bug in the refresh timers:

access token present, remaining duration: 860
registering expiring timer in: 800
Timer.init timer Access token expiring for duration: 800
registering expired timer in: 861
Timer.init timer Access token expired for duration: 861

But, it leads to this issue when it actually tries to refresh:

WebStorageStateStore.remove 3d4c516b06404439a366c93fd9b61b14
No matching state found in storage
Error from signinSilent: No matching state found in storage

So, I don't believe it to be work-around.

@brockallen brockallen added this to the 1.5.0 milestone May 5, 2018
@brockallen
Copy link
Member

I added a check that prevents loading the timers if there's no or undefined expiration.

@brockallen brockallen changed the title Access Token Expiration Issue Error when authorize response is missing expires_in response parameter May 19, 2018
@gitterchris
Copy link

gitterchris commented Aug 3, 2018

@bakedog417 Where you able to send the expires_in attribute with KeyCloak? We are having the same issue with implicit grant type. Without it, the automatic silent refresh does not work.

@bakedog417
Copy link
Author

bakedog417 commented Aug 3, 2018

@gitterchris No I was not able to get KeyCloak to send the expires_in parameter back-- it seems to have lost that functionality after version 3.3. What I ended up doing was defining it into a config object. Assuming you own the KeyCloak instance, you will know when the access token expires, so you can do something like this:

let config = {
            ...
            loadUserInfo: true,
            automaticSilentRenew:true,
            //Store user token in localstorage to stay logged in between tabs
            userStore: new WebStorageStateStore({store: window.localStorage}),
            //Not a real oidc-client param
            expires_in:900
        };

Then, later:

this.mgr.signinSilentCallback(window.location.href+`&expires_in=${config.expires_in}`)

and

this.mgr.signinRedirectCallback(window.location.href+`&expires_in=${config.expires_in}`)

Obviously, this is not the cleanest solution but it works. oidc-client will add the expires_in time to the current time to produce a "expires_at" attribute that is persisted in sessionStorage (or somewhere else if you like). This has worked out so far in that silent refreshes are working.

Hope this helps!

@gitterchris
Copy link

gitterchris commented Aug 3, 2018

Thanks for your response. I have tried the same thing and it works. Anyway, KeyCloak is working on bringing back the expires_in and token_type attributes in the next release.

https://issues.jboss.org/browse/KEYCLOAK-7695

@imduffy15
Copy link

Looks like KEYCLOAK-7695 has been merged and is part of Keycloak 4.4.0 :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

No branches or pull requests

4 participants