Merge 8e0e489a67
into d6e37fa741
This commit is contained in:
commit
6004128cdb
2 changed files with 27 additions and 5 deletions
|
@ -41,8 +41,14 @@ type AuthStorage interface {
|
||||||
// registered the refresh_token grant type in advance
|
// registered the refresh_token grant type in advance
|
||||||
//
|
//
|
||||||
// * TokenExchangeRequest as returned by ValidateTokenExchangeRequest
|
// * TokenExchangeRequest as returned by ValidateTokenExchangeRequest
|
||||||
CreateAccessAndRefreshTokens(ctx context.Context, request TokenRequest, currentRefreshToken string) (accessTokenID string, newRefreshTokenID string, expiration time.Time, err error)
|
//
|
||||||
TokenRequestByRefreshToken(ctx context.Context, refreshTokenID string) (RefreshTokenRequest, error)
|
// CreateAccessAndRefreshToken creates both access and refresh tokens.
|
||||||
|
// The returned refresh token is the actual token value that will be passed
|
||||||
|
// directly to the client. The storage implementation is responsible for
|
||||||
|
// creating the complete refresh token (JWT or opaque format). For refresh tokens,
|
||||||
|
// in either format, the token itself serves as both the identifier and the credential.
|
||||||
|
CreateAccessAndRefreshTokens(ctx context.Context, request TokenRequest, currentRefreshToken string) (accessTokenID string, newRefreshToken string, expiration time.Time, err error)
|
||||||
|
TokenRequestByRefreshToken(ctx context.Context, refreshToken string) (RefreshTokenRequest, error)
|
||||||
|
|
||||||
TerminateSession(ctx context.Context, userID string, clientID string) error
|
TerminateSession(ctx context.Context, userID string, clientID string) error
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,13 @@ func CreateTokenResponse(ctx context.Context, request IDTokenRequest, client Cli
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// createTokens delegates token creation to the appropriate storage method based on
|
||||||
|
// the request type and requirements. It returns an access token ID and expiration
|
||||||
|
// in all cases, but the refresh token handling varies:
|
||||||
|
// - When needsRefreshToken() returns true: calls CreateAccessAndRefreshTokens,
|
||||||
|
// which returns both tokens. The newRefreshToken will contain the actual token value.
|
||||||
|
// - When needsRefreshToken() returns false: calls CreateAccessToken only.
|
||||||
|
// The newRefreshToken will be an empty string in this case.
|
||||||
func createTokens(ctx context.Context, tokenRequest TokenRequest, storage Storage, refreshToken string, client AccessTokenClient) (id, newRefreshToken string, exp time.Time, err error) {
|
func createTokens(ctx context.Context, tokenRequest TokenRequest, storage Storage, refreshToken string, client AccessTokenClient) (id, newRefreshToken string, exp time.Time, err error) {
|
||||||
ctx, span := tracer.Start(ctx, "createTokens")
|
ctx, span := tracer.Start(ctx, "createTokens")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
@ -77,7 +84,7 @@ func createTokens(ctx context.Context, tokenRequest TokenRequest, storage Storag
|
||||||
return storage.CreateAccessAndRefreshTokens(ctx, tokenRequest, refreshToken)
|
return storage.CreateAccessAndRefreshTokens(ctx, tokenRequest, refreshToken)
|
||||||
}
|
}
|
||||||
id, exp, err = storage.CreateAccessToken(ctx, tokenRequest)
|
id, exp, err = storage.CreateAccessToken(ctx, tokenRequest)
|
||||||
return
|
return id, "", exp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func needsRefreshToken(tokenRequest TokenRequest, client AccessTokenClient) bool {
|
func needsRefreshToken(tokenRequest TokenRequest, client AccessTokenClient) bool {
|
||||||
|
@ -95,6 +102,15 @@ func needsRefreshToken(tokenRequest TokenRequest, client AccessTokenClient) bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateAccessToken creates an access token and may return a refresh token from storage.
|
||||||
|
// This function always creates the access token using the ID returned from storage.
|
||||||
|
// The refresh token is obtained from the storage layer and passed through unchanged.
|
||||||
|
// Whether a refresh token is included depends on the request:
|
||||||
|
// - Authorization code flow with offline_access scope: returns refresh token
|
||||||
|
// - Refresh token grant (rotation): returns new refresh token
|
||||||
|
// - Client credentials, implicit flow: returns empty string
|
||||||
|
//
|
||||||
|
// The function returns both tokens to support all flows with a single signature.
|
||||||
func CreateAccessToken(ctx context.Context, tokenRequest TokenRequest, accessTokenType AccessTokenType, creator TokenCreator, client AccessTokenClient, refreshToken string) (accessToken, newRefreshToken string, validity time.Duration, err error) {
|
func CreateAccessToken(ctx context.Context, tokenRequest TokenRequest, accessTokenType AccessTokenType, creator TokenCreator, client AccessTokenClient, refreshToken string) (accessToken, newRefreshToken string, validity time.Duration, err error) {
|
||||||
ctx, span := tracer.Start(ctx, "CreateAccessToken")
|
ctx, span := tracer.Start(ctx, "CreateAccessToken")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
@ -110,12 +126,12 @@ func CreateAccessToken(ctx context.Context, tokenRequest TokenRequest, accessTok
|
||||||
validity = exp.Add(clockSkew).Sub(time.Now().UTC())
|
validity = exp.Add(clockSkew).Sub(time.Now().UTC())
|
||||||
if accessTokenType == AccessTokenTypeJWT {
|
if accessTokenType == AccessTokenTypeJWT {
|
||||||
accessToken, err = CreateJWT(ctx, IssuerFromContext(ctx), tokenRequest, exp, id, client, creator.Storage())
|
accessToken, err = CreateJWT(ctx, IssuerFromContext(ctx), tokenRequest, exp, id, client, creator.Storage())
|
||||||
return
|
return accessToken, newRefreshToken, validity, err
|
||||||
}
|
}
|
||||||
_, span = tracer.Start(ctx, "CreateBearerToken")
|
_, span = tracer.Start(ctx, "CreateBearerToken")
|
||||||
accessToken, err = CreateBearerToken(id, tokenRequest.GetSubject(), creator.Crypto())
|
accessToken, err = CreateBearerToken(id, tokenRequest.GetSubject(), creator.Crypto())
|
||||||
span.End()
|
span.End()
|
||||||
return
|
return accessToken, newRefreshToken, validity, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateBearerToken(tokenID, subject string, crypto Crypto) (string, error) {
|
func CreateBearerToken(tokenID, subject string, crypto Crypto) (string, error) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue