-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Description
Describe the bug
I came across a strage behavior (seemingly a bug) regarding the refresh token expiration.
Under some (unknown) circumstances, the refresh_token issued by Keycloak contains an exp claim timestamp that is before the iat timestamp, e.g.:
"exp": 1652513276,
"iat": 1652529209,
This happens when retrieving an access token + refresh token from the https://kc-host/realms/my-realm/protocol/openid-connect/token endpoint using the authorization_code grant type.
Likewise, the response from the token endpoint contains a negative refresh_expires_in value:
{
"access_token": "eyJhbGciOiJ...",
"expires_in": 300,
"refresh_expires_in": -15933,
"refresh_token": "eyJhbGciOiJ...",
"token_type": "Bearer",
"id_token":" eyJhbGciOiJ...",
"not-before-policy": 0,
"session_state": "fa8347b3-4717-4bd6-a061-99f087aebf7e",
"scope": "openid"
}
Other timestamps/expirations are fine however (e.g., access token and KEYCLOAK_IDENTITY cookie in the same request showed OK).
I stumbled across this issue by recognizing a frequent "hard" refresh of my frontend client, since the regular refresh of the access token fails (due to the invalid refresh token, obviously). This led me to investigating said problem with the refesh token.
Noteworthy:
- When logging out of the Keycloak session completely, the problem is gone on next login (exp timestamp with proper offset in the future)
- We use an IdP during login (Azure AD)
Version
17.0.1
Expected behavior
Refresh token expiration to be positive and as configured, e.g.:
"refresh_expires_in": 1800
Actual behavior
Refresh token expiration is negative, e.g.:
"refresh_expires_in": -15933
How to Reproduce?
Token lifespan relevant realm config:
"revokeRefreshToken": false,
"refreshTokenMaxReuse": 0,
"accessTokenLifespan": 300,
"accessTokenLifespanForImplicitFlow": 900,
"ssoSessionIdleTimeout": 43200,
"ssoSessionMaxLifespan": 86400,
"ssoSessionIdleTimeoutRememberMe": 0,
"ssoSessionMaxLifespanRememberMe": 0,
"offlineSessionIdleTimeout": 2592000,
"offlineSessionMaxLifespanEnabled": false,
"offlineSessionMaxLifespan": 5184000,
"clientSessionIdleTimeout": 1800,
"clientSessionMaxLifespan": 36000,
"clientOfflineSessionIdleTimeout": 0,
"clientOfflineSessionMaxLifespan": 0,
"accessCodeLifespan": 60,
"accessCodeLifespanUserAction": 300,
"accessCodeLifespanLogin": 1800,
Realm client config:
{
"clientId": "my-client",
"description": "",
"rootUrl": "redacted",
"adminUrl": "",
"baseUrl": "/",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": true,
"clientAuthenticatorType": "client-secret",
"redirectUris": redacted,
"webOrigins": [
"+"
],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"oauth2.device.authorization.grant.enabled": "false",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"use.refresh.tokens": "true",
"exclude.session.state.from.auth.response": "false",
"oidc.ciba.grant.enabled": "false",
"saml.artifact.binding": "false",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"fullScopeAllowed": false,
"nodeReRegistrationTimeout": -1
},Client application:
- Chrome on macOS
Anything else?
Interestingly, until now, I only happened to experience this problem with Chrome on macOS. No issue so far on Chrome on Windows.
On the macOS machine, however, it also does not occur consistently. We have multiple Keycloak instances (for different environments), with the exact same Keycloak deployed (17.0.1) and identical realm configurations. On some instances I face the problem, while others are fine. Also, the problem is not always present.
I somewhat feel like there's a correlation that this problem occurs when I continue using the affected web frontend after the macbook was on standby/hibernate for a couple of hours.