Refresh access_token via refresh_token in Keycloak
Asked Answered
H

4

78

I need to make the user keep login in the system if the user's access_token get expired and user want to keep login. How can I get newly updated access_token with the use of refresh_token on Keycloak?

I am using vertx-auth for the auth implementation with Keycloak on vert.x. Is it possible to refresh access_token with vertx-auth or Keycloak's REST API itself? Or what will be another implementation of this?

Havener answered 17/7, 2018 at 16:33 Comment(0)
H
167

keycloak has REST API for creating an access_token using refresh_token. It is a POST endpoint with application/x-www-form-urlencoded

Here is how it looks:

Method: POST
URL: https://keycloak.example.com/auth/realms/myrealm/protocol/openid-connect/token
Body type: x-www-form-urlencoded
Form fields:    
client_id : <my-client-name>
grant_type : refresh_token
refresh_token: <my-refresh-token>

This will give you new access token using refresh token.

NOTE: if your refresh token is expired it will throw 400 exception in that you can make user login again.

Check out a sample in Postman, you can develop and corresponding API using this.

Sample in Postman

Heywood answered 17/7, 2018 at 17:40 Comment(11)
I tried this with 2.5.4 and it still requires the client secret for this request. It makes now sense though as to why the client secret will be required if the refresh token is being provided.Undermanned
The client secret is required only if it is a confidential client. Public clients do not require the client secret.Undermanned
Can someone explain why the client secret is required when refreshing a token for a confidential client?Devanagari
@all ,Why refresh token is jwt format? stateless but google and auth0 use stateful.Hartsock
@Devanagari confidential client in Keycloak is meant to server applications, where storing a client secret is secure. Take a look on the docs (here)[keycloak.org/docs/6.0/server_admin/#oidc-clients]Eiderdown
Hi all, I know it's old but I want to ask a bit. I use login phase to get the init token with aud=app1 for example. But when the token is expired, I tried and to refresh the token by calling http://{uri}/realms/{my_realm}/protocol/openid-connect/token, and the result I get the token with different aud, like aud=app2. So how can It be and how can I change app2 to app1, thanks!Wynn
@BasselKh so client secret is not needed? If so may I ask your client configuration? ThanksBilateral
@Bilateral : grant_type: refresh_token , client_id: your client id , refresh_token: the original refresh tokenPuritanism
It seems this request also returns a new refresh token. Is this correct? If we want to renew an access token, the refresh token should be refreshed as well? Or the correct flow will be: use access tokens -> if access token expires: use refresh token to get new access token -> if refresh token expires: login and get new refresh and access token. By always creating a new refresh token, it seems that logout could never hapen.Convention
Please add client_secret to the bodyTopeka
Below article was also helpful for me -> developers.redhat.com/blog/2020/11/24/…Coleen
T
11

@maslick is correct you have to supply the client secret too, no need for authorization header in this case:

http://localhost:8080/auth/realms/{realm}/protocol/openid-connect/token

enter image description here

In case of expired refresh token it returns:

enter image description here

If you don't add the secret you get 401 unauthorized even though the refresh token is correct

enter image description here

Threemaster answered 3/7, 2021 at 11:56 Comment(1)
I have just tested it, you only need the client secret if the client that issued the token is confidentialBilateral
A
3

Extending Yogendra Mishra's answer. Note that client_id and client_secret can also be sent in Authorization header.

Authorization: Basic ${Base64(<client_id>:<client_secret>)}

This works for both initial token call (without refresh token) and refresh token call to /openid-connect/token endpoint

Basic auth1

don't need to send clientid and secret in body after setting auth headers

Reference: https://developer.okta.com/docs/reference/api/oidc/#client-secret

Azerbaijani answered 10/2, 2022 at 13:39 Comment(0)
B
1

I tried with 4.8.2.Final, it gives following unauthorized_client even with previous access token as 'Bearer'. Then I tried with Basic YXBwLXByb3h5OnNlY3JldA== in Authorization header. Then it worked, But still I'm not sure that I am doing right thing.

Baer answered 28/1, 2019 at 5:38 Comment(3)
For the Authorization headers it all comes down to what the server is looking for in the header value. If this works then you're probably not incorrect.Kab
You're probably using a confidential client, so you need to include client_secret in the requestMilkman
why would anyone want to use refresh token if I have to pass client_secret for confidential client? IMO, Keycloak should return access_token just by passing client_id and refresh_token since it acts like a secret.Compote

© 2022 - 2024 — McMap. All rights reserved.