spring-projects / spring-projects/spring-security
Allow customization of OIDC sid creation from SessionInformation
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.6k
- Forks
- 6.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 52
Description
Expected Behavior
OAuth2AuthorizationCodeAuthenticationProvider and OidcLogoutAuthenticationProvider should provide a way to customize the SessionInformation put into the token context which is later used by the JwtGenerator to produce the sid claim for the OIDC id token.
Current Behavior
The OAuth2AuthorizationCodeAuthenticationProvider uses a SessionRegistry to find the current user session of the authenticated user and if successful it creates a SHA-256 hash over the session id (because the session id is sensitive information). It creates a new SessionInformation with this hash value instead of the original session id and stores this in the token context. The JwtGenerator then uses this information from the context to add a sidclaim with the hash value to the generated OIDC id token.
The OidcLogoutAuthenticationProvider uses the same hash mechanism later to verify that a provided id token hint matches the currently open user session. In both cases the hashing code is hardcoded in the respective classes as private methods.
Context
During an OIDC login (OAuth2 with scope openid) an id token is created. To support the OIDC's back-channel logout feature, a sid claim is added to the id token. According to https://openid.net/specs/openid-connect-backchannel-1_0.html#BCSupport the sid is an opaque string identifier "used to identify distinct sessions at an OP".
As mentioned under Current Behavior, the source of this sid claim is the hashed id of the current Spring session. This behavior is currently hardcoded in the mentioned provider classes with no way to override it.
We were using a custom public session identifier in our authorization server implementation as sid already before Spring added this sid handling. The main reason is that we use this sid also in audit logs and therefore want more control over the format and creation of this value (e.g. it should be more human-readable). We store this identifier in the details of the Authentication object (principal) and currently use a OAuth2TokenCustomizer to override the sid claim of the id token during JWT creation with our own value. Just for overriding the claim in the JWT, this works fine, but it is not compatible with the code in OidcLogoutAuthenticationProvider and thus fails the id token session check there.
Therefore, it would be nice if the SessionInformation related code in OAuth2AuthorizationCodeAuthenticationProvider and OidcLogoutAuthenticationProvider (especially the hashing part) would be customizable. For example, by using an extra SessionIdConverter dependency that gets the current principal and session id and returns the value to be used as sid. If that converter could be externally configured, we could set a custom implementation and would not need to overwrite the claim in the token generator. That way also the OIDC logout code would work out of the box.
Thank you!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading OAuth2AuthorizationCodeAuthenticationProvider and OidcLogoutAuthenticationProvider, focusing on their SessionInformation handling and private hashing methods. Trace how the value reaches JwtGenerator and is later checked against an ID token hint. Done means an externally configurable sid creation mechanism is used consistently for token generation and OIDC logout verification.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- authentication, backend, security
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100