3

I am trying to use Keycloak admin REST API to recreate an access token when I have a valid refresh token.

I have accomplished that, by invoking with POST /auth/realms/{realm}/protocol/openid-connect/token.

The problem is that the endpoint also returns a new refresh token each time. Is this the way a JWT authorisation flow should work?

I think the correct flow would be to only get a new access token when the auth endpoint is invoked, and when the refresh token expires, to sign in again to acquire a new refresh token; Not to get a new refresh token each time we query for a new access token.

I have also read this stack overflow post. Am I missing something here? You may find a pic with the request below: enter image description here

Antonis S
  • 733
  • 6
  • 15

2 Answers2

2

Using one-time refresh token is a modern best practice, because that allows the authorization server to kick out the user if the same refresh token is used twice.

How can that happen? well for example if the refresh token is stolen, then the hacker and your application will both try to use it! Otherwise it is a bit harder to detect hackers in the system

Tore Nestenius
  • 16,431
  • 5
  • 30
  • 40
0

First of all you mix up two things. Open ID Connect Authentication with JWT and Oauth authorization tokens and refresh tokens.

This are two different objects. You will get a new OAuth refresh token each time you obtain an access token. This is the way OAuth grants you a "endless session" but with the option to deny a new access token at any try of exchange.

Also see from RFC https://datatracker.ietf.org/doc/html/rfc6749#section-1.5

  +--------+                                           +---------------+
  |        |--(A)------- Authorization Grant --------->|               |
  |        |                                           |               |
  |        |<-(B)----------- Access Token -------------|               |
  |        |               & Refresh Token             |               |
  |        |                                           |               |
  |        |                            +----------+   |               |
  |        |--(C)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(D)- Protected Resource --| Resource |   | Authorization |
  | Client |                            |  Server  |   |     Server    |
  |        |--(E)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(F)- Invalid Token Error -|          |   |               |
  |        |                            +----------+   |               |
  |        |                                           |               |
  |        |--(G)----------- Refresh Token ----------->|               |
  |        |                                           |               |
  |        |<-(H)----------- Access Token -------------|               |
  +--------+           & Optional Refresh Token        +---------------+

               Figure 2: Refreshing an Expired Access Token
Markus
  • 1,465
  • 4
  • 18
  • 29
  • 1
    Thanks a lot for the response! Could you please clarify if there is an option at keycloak to avoid returning a refresh token when a query for an access token is made, In order to enforce logout? Or we should just avoid returning the new refresh token in subsequent calls to the consumer of our auth services which utilises keycloak? In other words the question is: How can we make the return of the refresh token optional - via a keycloak option or via our implementation? – Antonis S Dec 20 '21 at 15:03