fix: bind OIDC token claims to the logged-in user and keep the session ID stable #15

Merged
robinp2000 merged 1 commit from fix/oidc-jwt-token into main 2026-10-09 11:57:39 +02:00
Owner

What

  • ID and access tokens of a logged-in user carry sub (the user's uuid) and sid instead of the hard-coded placeholders. E-mail address and role are not part of the tokens, they are delivered by the UserInfo endpoint.
  • sid is the SHA-256 (base64url, no padding) of the session ID after the first login step. It is created once per session and kept in the verification token object, so it does not change when a later login step-up replaces the session id.
  • Fail with a clear message if the user has no session ID.
  • Authorizations store the sid of their ID token in an own column, so logout deletes them with one query instead of parsing every authorization.
  • Fix OidcLogoutHandler: it read the user from getDetails(), but instead getPrincipal() should be used, because getDetails() is only relevant to keep token information during step-up authentication, so it doesn't reflect the newest user token state and may be null.

Why

  • Every token claimed to belong to "admin / Max Mustermann".
  • Clients need a stable sid to match security events and logout to a single device, and logout must remove exactly the authorizations of that session.

Tests

  • OidcJWTTest (8), OidcLogoutHandlerTest (4), OidcAuthorizationServiceTest (1).
  • Not covered by an automated test: the full authorization code flow and the transaction of the derived delete.
## What - ID and access tokens of a logged-in user carry `sub` (the user's uuid) and `sid` instead of the hard-coded placeholders. E-mail address and role are not part of the tokens, they are delivered by the UserInfo endpoint. - `sid` is the SHA-256 (base64url, no padding) of the session ID after the first login step. It is created once per session and kept in the verification token object, so it does not change when a later login step-up replaces the session id. - Fail with a clear message if the user has no session ID. - Authorizations store the `sid` of their ID token in an own column, so logout deletes them with one query instead of parsing every authorization. - Fix `OidcLogoutHandler`: it read the user from `getDetails()`, but instead `getPrincipal()` should be used, because `getDetails()` is only relevant to keep token information during step-up authentication, so it doesn't reflect the newest user token state and may be null. - ## Why - Every token claimed to belong to "admin / Max Mustermann". - Clients need a stable `sid` to match security events and logout to a single device, and logout must remove exactly the authorizations of that session. ## Tests - `OidcJWTTest` (8), `OidcLogoutHandlerTest` (4), `OidcAuthorizationServiceTest` (1). - Not covered by an automated test: the full authorization code flow and the transaction of the derived delete.
fix: bind OIDC token claims to the logged-in user and keep the session ID stable
All checks were successful
CI / build (pull_request) Successful in 2m11s
752364d045
robinp2000 deleted branch fix/oidc-jwt-token 2026-10-09 11:57:39 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
robinp2000/dachshund-auth-provider!15
No description provided.