-
Bug
-
Resolution: Done
-
Undefined
-
None
-
False
-
-
False
-
-
Before reporting an issue
[X] I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.
Area
oidc
Describe the bug
Currently token revocation does this:
- For access token, it revokes only the particular access token (OK)
- When invoked with the refresh token of client client-a and user user-a with the token created with user session session1, it:
- Deletes the consent granted by the user-a to client-a
- Deletes all client sessions of client client-a of all user sessions for user user-a . So it deletes also the client sessions, which are unrelated to the particular session session1, but possibly also to other user sessions
The behaviour is not compliant with the specification as the specs mention to only invalidate refresh-token and related access-tokens issued during same authorization grant, which effectively means droping just this particular client session (See https://datatracker.ietf.org/doc/html/rfc7009#section-2.1) . Also misleading for the users as can be seen in the discussion https://github.com/keycloak/keycloak/discussions/27815 and some other report by our customer.
AFAIK the reasoning behind deleting of all client sessions of all user sessions might be the fact, that we are dropping also the granted consent. During refresh-token request, we are checking that granted consent is still valid (for clients with Consent Required enabled). So if we drop only single session session1, the other refresh tokens would be effectively invalid as well.
If we want to update the behaviour, our options are:
1) Don't delete the granted consent. Revoke only client session for particular user session session1, which was referenced in the refresh-token
2) Still delete the granted consent. Revoke only client session for particular user session session1, which was referenced in the refresh-token.
The option (2) means that for clients with Consent Required, the other client sessions will be effectively revoked as well (due the fact that refresh-token request checks if consent is still granted). So this would be still a bit buggy behaviour IMO.
IMO, we should do the option (1) and document in the upgrading guide about this. If there is someone, who want the old behaviour, we can handle that with client-policy-executor as a follow-up (if there is a request for this).
Version
nightly (from 2024-12-02)
Regression
[ ] The issue is a regression
Expected behavior
Only one session is invalidated. The granted consent should be probably kept (See description for more details)
Actual behavior
All sessions are invalidated.
How to Reproduce?
1. Create a session with a test user
```
curl -d "client_id=<test client id>" \ -d "client_secret=<test client secret>" \ -d "grant_type=password" \ -d "username=<test user name>" \ -d "password=<test user password>" \ -d "scope=openid" \ "http://<domain>/auth/realms/<realm name>/protocol/openid-connect/token" | jq .refresh_token
```
2. Create another session with the same user
```
curl -d "client_id=<test client id>" \ -d "client_secret=<test client secret>" \ -d "grant_type=password" \ -d "username=<test user name>" \ -d "password=<test user password>" \ -d "scope=openid" \ "http://<domain>/auth/realms/<realm name>/protocol/openid-connect/token"
```
3. Check the two sessions are created in the admin console
4. Revoke the session created in step 1
```
curl -d "client_id=<test client id>" \ -d "client_secret=<test client secret>" \ -d "token_type_hint=refresh_token" \ -d "token=<refresh token>" \ "http://<domain>/auth/realms/<realm name>/protocol/openid-connect/revoke"
```
For <refresh_token>, use the refresh token issued in step1.
5. Check the sessions in the admin console
It is expected that the session created in step2 still exists, but actually, both sessions are revoked.
Anything else?
No response
- links to