feat(server): introduce a token issuer abstraction#4893
Open
nabokihms wants to merge 1 commit into
Open
Conversation
fcf9f5c to
f144e45
Compare
Token issuance was spread across every grant as long positional calls to Server.newIDToken/newAccessToken plus copy-pasted refresh-token creation. This introduces a small domain around it: Authorization the authenticated subject and the client permission TokenSet the tokens produced from it tokenSigner access and id JWT minting, owning cross-client audience refreshTokens refresh-token persistence and offline-session bookkeeping tokenIssuer composes the above; writeTokenResponse handles transport Every grant now builds an Authorization and hands it to the issuer: password, client_credentials, token_exchange, authorization_code, the approval implicit/hybrid path and the refresh grant. Server.newIDToken/newAccessToken are gone; callers and tests build an Authorization and go through the signer. refreshTokens.create unifies the create-and-record-offline-session logic that the authorization_code and password grants had copied with a subtle divergence: password now persists connector data on the refresh token and stops overwriting a stored offline session with empty connector data, matching the authorization_code grant and the refresh grant's own read path. Refresh rotation and the refreshContext removal are a separate change. Signed-off-by: maksim.nabokikh <max.nabokih@gmail.com>
f144e45 to
d94e6bb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
A token-issuance core for the
serverpackage. Every grant reduces to producing anAuthorization, and the issuer turns it into aTokenSet.What this PR does / why we need it
Token issuance was spread across every grant as long positional calls to
Server.newIDToken/newAccessToken, plus refresh-token creation that was copy-pasted between two grants.token_issuer.gogives it a small domain:Authorization(the authenticated subject and the client permission) andTokenSet(the tokens produced from it) value objects.tokenSignerfor access and id JWT minting, owning cross-client audience resolution internally.refreshTokensfor refresh-token persistence, unifying the create-and-record-offline-session logic that the authorization_code and password grants had copied. Rollback on a failed offline-session write is preserved.tokenIssuer.Issue(auth, wantRefresh)composing them, withwriteTokenResponseas a separate transport helper.Every grant is migrated: password, client_credentials, token_exchange, authorization_code, the approval implicit/hybrid path and the refresh grant.
Server.newIDToken/newAccessTokenare removed; callers and tests build anAuthorizationand go through the signer. Unit tests cover the issuer and the refresh store.Special notes for your reviewer
One deliberate behaviour change. Unifying
refreshTokens.createaligns the password grant with the authorization_code grant's connector-data handling:ConnectorData(previously left empty). In the common case this is a no-op: the refresh token and the offline session get the sameidentity.ConnectorData, and the refresh grant reads the same value from either.if len(ConnectorData) > 0) instead of unconditionally overwriting, so an empty re-auth no longer clobbers previously stored connector data. This matches both the authorization_code grant and the refresh grant's own read logic.Refresh rotation (
updateRefreshToken) and therefreshContextremoval, which are entangled with introspection's shared token lookup, come in a follow-up.