mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:37:30 +00:00
feat(OIDC): support token revocation of V2 tokens (#6203)
This PR adds support for OAuth2 token revocation of V2 tokens. Unlike with V1 tokens, it's now possible to revoke a token not only from the authorized client / client which the token was issued to, but rather from all trusted clients (audience)
This commit is contained in:
@@ -20,9 +20,11 @@ type OIDCSessionWriteModel struct {
|
||||
AuthMethods []domain.UserAuthMethodType
|
||||
AuthTime time.Time
|
||||
State domain.OIDCSessionState
|
||||
AccessTokenID string
|
||||
AccessTokenCreation time.Time
|
||||
AccessTokenExpiration time.Time
|
||||
RefreshTokenID string
|
||||
RefreshToken string
|
||||
RefreshTokenExpiration time.Time
|
||||
RefreshTokenIdleExpiration time.Time
|
||||
|
||||
@@ -46,10 +48,14 @@ func (wm *OIDCSessionWriteModel) Reduce() error {
|
||||
wm.reduceAdded(e)
|
||||
case *oidcsession.AccessTokenAddedEvent:
|
||||
wm.reduceAccessTokenAdded(e)
|
||||
case *oidcsession.AccessTokenRevokedEvent:
|
||||
wm.reduceAccessTokenRevoked(e)
|
||||
case *oidcsession.RefreshTokenAddedEvent:
|
||||
wm.reduceRefreshTokenAdded(e)
|
||||
case *oidcsession.RefreshTokenRenewedEvent:
|
||||
wm.reduceRefreshTokenRenewed(e)
|
||||
case *oidcsession.RefreshTokenRevokedEvent:
|
||||
wm.reduceRefreshTokenRevoked(e)
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
||||
@@ -65,6 +71,7 @@ func (wm *OIDCSessionWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
oidcsession.AccessTokenAddedType,
|
||||
oidcsession.RefreshTokenAddedType,
|
||||
oidcsession.RefreshTokenRenewedType,
|
||||
oidcsession.RefreshTokenRevokedType,
|
||||
).
|
||||
Builder()
|
||||
|
||||
@@ -91,9 +98,15 @@ func (wm *OIDCSessionWriteModel) reduceAdded(e *oidcsession.AddedEvent) {
|
||||
}
|
||||
|
||||
func (wm *OIDCSessionWriteModel) reduceAccessTokenAdded(e *oidcsession.AccessTokenAddedEvent) {
|
||||
wm.AccessTokenID = e.ID
|
||||
wm.AccessTokenExpiration = e.CreationDate().Add(e.Lifetime)
|
||||
}
|
||||
|
||||
func (wm *OIDCSessionWriteModel) reduceAccessTokenRevoked(e *oidcsession.AccessTokenRevokedEvent) {
|
||||
wm.AccessTokenID = ""
|
||||
wm.AccessTokenExpiration = e.CreationDate()
|
||||
}
|
||||
|
||||
func (wm *OIDCSessionWriteModel) reduceRefreshTokenAdded(e *oidcsession.RefreshTokenAddedEvent) {
|
||||
wm.RefreshTokenID = e.ID
|
||||
wm.RefreshTokenExpiration = e.CreationDate().Add(e.Lifetime)
|
||||
@@ -105,6 +118,14 @@ func (wm *OIDCSessionWriteModel) reduceRefreshTokenRenewed(e *oidcsession.Refres
|
||||
wm.RefreshTokenIdleExpiration = e.CreationDate().Add(e.IdleLifetime)
|
||||
}
|
||||
|
||||
func (wm *OIDCSessionWriteModel) reduceRefreshTokenRevoked(e *oidcsession.RefreshTokenRevokedEvent) {
|
||||
wm.RefreshTokenID = ""
|
||||
wm.RefreshTokenExpiration = e.CreationDate()
|
||||
wm.RefreshTokenIdleExpiration = e.CreationDate()
|
||||
wm.AccessTokenID = ""
|
||||
wm.AccessTokenExpiration = e.CreationDate()
|
||||
}
|
||||
|
||||
func (wm *OIDCSessionWriteModel) CheckRefreshToken(refreshTokenID string) error {
|
||||
if wm.State != domain.OIDCSessionStateActive {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "OIDCS-s3hjk", "Errors.OIDCSession.RefreshTokenInvalid")
|
||||
@@ -118,3 +139,29 @@ func (wm *OIDCSessionWriteModel) CheckRefreshToken(refreshTokenID string) error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wm *OIDCSessionWriteModel) CheckAccessToken(accessTokenID string) error {
|
||||
if wm.State != domain.OIDCSessionStateActive {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "OIDCS-KL2pk", "Errors.OIDCSession.Token.Invalid")
|
||||
}
|
||||
if wm.AccessTokenID != accessTokenID {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "OIDCS-JLKW2", "Errors.OIDCSession.Token.Invalid")
|
||||
}
|
||||
if wm.AccessTokenExpiration.Before(time.Now()) {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "OIDCS-3j3md", "Errors.OIDCSession.Token.Invalid")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wm *OIDCSessionWriteModel) CheckClient(clientID string) error {
|
||||
for _, aud := range wm.Audience {
|
||||
if aud == clientID {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "OIDCS-SKjl3", "Errors.OIDCSession.InvalidClient")
|
||||
}
|
||||
|
||||
func (wm *OIDCSessionWriteModel) OIDCRefreshTokenID(refreshTokenID string) string {
|
||||
return wm.AggregateID + TokenDelimiter + refreshTokenID
|
||||
}
|
||||
|
Reference in New Issue
Block a user