I can’t figure out where the problem is coming from.
I first created the proper login requests for the tokens using Postman. I’m able to get both the refresh_token and access_token. I can also refresh the access_token using Postman.
This is the “Login” scheme:
This refreshes the access_token successfully:
Now, you can see the C# code to the right. This code works for the “Login”, i.e. I get the initial access_token and refresh_token.
However, when I later try to refresh the access_token, I’m getting this error:
keycloak "error": "invalid_grant", "error_description": "Invalid refresh token"
I took a look at both decoded refresh_token JWTs (from Postman and from my C# code) and couldn’t find significant differences.
This is from Postman:
And this from my C# request:
I’m a bit confused and don’t quite see where the problem is coming from. Especially as the 1st request is going though…
mbonn
January 20, 2025, 10:28am
2
“Invalid refresh token” sounds as you are re-using an alredy used token. As far as I know, the default in KC is that you can use a refresh token only once. And the System.Net.Http.HttpClient is intended to be instantiated once per application, rather than per-use:
1 Like
Revoke Refresh Token under realm settings is optional and by default disabled, unless not explicitly enabled.
mbonn
January 20, 2025, 2:24pm
4
Ah ok, sorry for the mix-up. I enabled it so long ago that i now consider it the default, especially because it is recommended for security reasons…
Rhywden
January 21, 2025, 10:13am
5
Revoke Refresh Token is currently disabled.
And the actual code uses the HttpClientFactory to create a HttpClient so that isn’t the issue either.
If the sequence of request works from postman but not from C# code, the issue must be in the C# code …
You obviously do not run the C# code from postman, you had to put it in a C# project and build it, so the problem must be somewhere in your C# code, and I think probably not related to Keycloak
Ensure that you pass the same scope in the refresh token request and probably check:
opened 01:59PM - 26 Aug 22 UTC
closed 06:49AM - 15 Apr 24 UTC
area/oidc
kind/bug
priority/important
team/sre
status/missing-information
### Describe the bug
Context:
We are using onTokenExpired event of Keycloak fr… om 'keycloak-js' to refresh the access token upon expiry.
We call updateToken method when onTokenExpired is fired.
Issue:
This works mostly without any issues. But randomly we get 400 error when we try to refresh the token.
In our realm, access_token expires in 5 minutes and refresh_token expires in 30 minutes.
The updateToken calls https://abc.xyz.com/realms/my_realm/protocol/openid-connect/token with grant_type=refresh_token
It gives a new access_token and a NEW refresh_token each time it's called.
Subsequent updateToken call uses the refresh_token from previous request.
So in our setup access_token expires every 5 minutes -> updateToken called every 5 minutes -> We can new refresh_token every 5 minutes.
This works for hours and is expected to work till "SSO Session Max" which is set to 10 hours.
But randomly (can be after 2 hours or after 3-4 hours), https://abc.xyz.com/realms/my_realm/protocol/openid-connect/token gives 400 error. Message logged by KeyCloak around same time is:
WARN [org.keycloak.events] (executor-thread-246) type=REFRESH_TOKEN_ERROR, realmId=my_realm, clientId=client-web, userId=xxx, ipAddress=xyz error=invalid_token, grant_type=refresh_token, refresh_token_type=Refresh, refresh_token_id=8649a5b1-ca82-4908-a649-90e517050af6, client_auth_method=client-secret
The puzzle is:
1. We used a refresh_token which was created just 5 minutes back with validity of 30 minutes.
2. So refresh_token has not expired, then why do we get 400 error with no clear reason?
### Version
17.0.1
### Expected behavior
updateToken should be able to refresh access_token till "SSO Session Max" period which is set to 10 hours for our case.
### Actual behavior
A nonexpired refresh_token is treated as invalid_token
### How to Reproduce?
Maybe use the same setting as mine:
SSO Session Idle: 30 minutes
SSO Session Max: 10 hours
Access Token Lifespan: 5 minutes
### Anything else?
_No response_