feat: add CanTerminateSessionFromRequest interface (#418)
To support access to all claims in the id_token_hint (like a sessionID), this PR adds a new (optional) add-on interface to the Storage.
This commit is contained in:
parent
4c844da05e
commit
be89c3b7bc
2 changed files with 21 additions and 6 deletions
|
@ -34,12 +34,17 @@ func EndSession(w http.ResponseWriter, r *http.Request, ender SessionEnder) {
|
|||
RequestError(w, r, err)
|
||||
return
|
||||
}
|
||||
err = ender.Storage().TerminateSession(r.Context(), session.UserID, session.ClientID)
|
||||
redirect := session.RedirectURI
|
||||
if fromRequest, ok := ender.Storage().(CanTerminateSessionFromRequest); ok {
|
||||
redirect, err = fromRequest.TerminateSessionFromRequest(r.Context(), session)
|
||||
} else {
|
||||
err = ender.Storage().TerminateSession(r.Context(), session.UserID, session.ClientID)
|
||||
}
|
||||
if err != nil {
|
||||
RequestError(w, r, oidc.DefaultToServerError(err, "error terminating session"))
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, session.RedirectURI, http.StatusFound)
|
||||
http.Redirect(w, r, redirect, http.StatusFound)
|
||||
}
|
||||
|
||||
func ParseEndSessionRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.EndSessionRequest, error) {
|
||||
|
@ -60,11 +65,12 @@ func ValidateEndSessionRequest(ctx context.Context, req *oidc.EndSessionRequest,
|
|||
RedirectURI: ender.DefaultLogoutRedirectURI(),
|
||||
}
|
||||
if req.IdTokenHint != "" {
|
||||
claims, err := VerifyIDTokenHint[*oidc.TokenClaims](ctx, req.IdTokenHint, ender.IDTokenHintVerifier(ctx))
|
||||
claims, err := VerifyIDTokenHint[*oidc.IDTokenClaims](ctx, req.IdTokenHint, ender.IDTokenHintVerifier(ctx))
|
||||
if err != nil {
|
||||
return nil, oidc.ErrInvalidRequest().WithDescription("id_token_hint invalid").WithParent(err)
|
||||
}
|
||||
session.UserID = claims.GetSubject()
|
||||
session.IDTokenHintClaims = claims
|
||||
if req.ClientID != "" && req.ClientID != claims.GetAuthorizedParty() {
|
||||
return nil, oidc.ErrInvalidRequest().WithDescription("client_id does not match azp of id_token_hint")
|
||||
}
|
||||
|
|
|
@ -62,6 +62,14 @@ type AuthStorage interface {
|
|||
KeySet(context.Context) ([]Key, error)
|
||||
}
|
||||
|
||||
// CanTerminateSessionFromRequest is an optional additional interface that may be implemented by
|
||||
// implementors of Storage as an alternative to TerminateSession of the AuthStorage.
|
||||
// It passes the complete parsed EndSessionRequest to the implementation, which allows access to additional data.
|
||||
// It also allows to modify the uri, which will be used for redirection, (e.g. a UI where the user can consent to the logout)
|
||||
type CanTerminateSessionFromRequest interface {
|
||||
TerminateSessionFromRequest(ctx context.Context, endSessionRequest *EndSessionRequest) (string, error)
|
||||
}
|
||||
|
||||
type ClientCredentialsStorage interface {
|
||||
ClientCredentials(ctx context.Context, clientID, clientSecret string) (Client, error)
|
||||
ClientCredentialsTokenRequest(ctx context.Context, clientID string, scopes []string) (TokenRequest, error)
|
||||
|
@ -152,9 +160,10 @@ type StorageNotFoundError interface {
|
|||
}
|
||||
|
||||
type EndSessionRequest struct {
|
||||
UserID string
|
||||
ClientID string
|
||||
RedirectURI string
|
||||
UserID string
|
||||
ClientID string
|
||||
IDTokenHintClaims *oidc.IDTokenClaims
|
||||
RedirectURI string
|
||||
}
|
||||
|
||||
var ErrDuplicateUserCode = errors.New("user code already exists")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue