From 7f6d323ddef87cef569b116d8c7ad1de044baf62 Mon Sep 17 00:00:00 2001 From: ybelMekk Date: Sat, 22 Jan 2022 16:23:16 +0100 Subject: [PATCH] add: session management check to get `session_state` from OP response, generate a externalSessionID if none supported. --- pkg/openid/configuration.go | 9 +++++++++ pkg/openid/token.go | 12 ++++++------ pkg/router/handler_callback.go | 24 ++++++++++++++++++++---- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/pkg/openid/configuration.go b/pkg/openid/configuration.go index 8548327..24a2138 100644 --- a/pkg/openid/configuration.go +++ b/pkg/openid/configuration.go @@ -33,6 +33,7 @@ type Configuration struct { RequestParameterSupported bool `json:"request_parameter_supported"` RequestURIParameterSupported bool `json:"request_uri_parameter_supported"` RequestObjectSigningAlgValuesSupported []string `json:"request_object_signing_alg_values_supported"` + CheckSessionIframe string `json:"check_session_iframe,omitempty"` } type Supported []string @@ -71,3 +72,11 @@ func (c *Configuration) FetchJwkSet(ctx context.Context) (*jwk.Set, error) { return &jwkSet, nil } + +func (c *Configuration) FetchCheckSessionIframe() bool { + if c.CheckSessionIframe == "" { + return false + } + + return true +} diff --git a/pkg/openid/token.go b/pkg/openid/token.go index 67c8629..020a859 100644 --- a/pkg/openid/token.go +++ b/pkg/openid/token.go @@ -22,18 +22,18 @@ func (in *IDToken) Validate(opts ...jwt.ValidateOption) error { return nil } -func (in *IDToken) GetSID() (string, error) { - sid, ok := in.Token.Get("sid") +func (in *IDToken) GetStringClaim(claim string) (string, error) { + gotClaim, ok := in.Token.Get(claim) if !ok { - return "", fmt.Errorf("missing required 'sid' claim in id_token") + return "", fmt.Errorf("missing required '%s' claim in id_token", claim) } - sidString, ok := sid.(string) + claimString, ok := gotClaim.(string) if !ok { - return "", fmt.Errorf("'sid' claim is not a string") + return "", fmt.Errorf("'%s' claim is not a string", claim) } - return sidString, nil + return claimString, nil } func ParseIDToken(jwks jwk.Set, token *oauth2.Token) (*IDToken, error) { diff --git a/pkg/router/handler_callback.go b/pkg/router/handler_callback.go index 623c12a..92c3559 100644 --- a/pkg/router/handler_callback.go +++ b/pkg/router/handler_callback.go @@ -3,6 +3,7 @@ package router import ( "context" "fmt" + "github.com/google/uuid" "net/http" "time" @@ -82,6 +83,11 @@ func (h *Handler) codeExchangeForToken(ctx context.Context, loginCookie *openid. return tokens, nil } +func (h *Handler) sidClaimRequired() bool { + config := h.Provider.GetOpenIDConfiguration() + return config.FrontchannelLogoutSupported && config.FrontchannelLogoutSessionSupported +} + func (h *Handler) validateIDToken(idToken *openid.IDToken, loginCookie *openid.LoginCookie) (string, error) { validateOpts := []jwt.ValidateOption{ jwt.WithAudience(h.Provider.GetClientConfiguration().GetClientID()), @@ -103,7 +109,18 @@ func (h *Handler) validateIDToken(idToken *openid.IDToken, loginCookie *openid.L return "", err } - externalSessionID, err := idToken.GetSID() + var externalSessionID string + + switch true { + case h.sidClaimRequired(): + externalSessionID, err = idToken.GetStringClaim("sid") + case h.Provider.GetOpenIDConfiguration().FetchCheckSessionIframe(): + externalSessionID, err = idToken.GetStringClaim("session_state") + default: + // generate external sid + externalSessionID = h.GenerateExternalSessionID() + } + if err != nil { return "", fmt.Errorf("getting external session ID from id_token: %w", err) } @@ -111,7 +128,6 @@ func (h *Handler) validateIDToken(idToken *openid.IDToken, loginCookie *openid.L return externalSessionID, nil } -func (h *Handler) sidClaimRequired() bool { - config := h.Provider.GetOpenIDConfiguration() - return config.FrontchannelLogoutSupported && config.FrontchannelLogoutSessionSupported +func (h *Handler) GenerateExternalSessionID() string { + return fmt.Sprintf("%s:%s:%s", h.Config.OpenID.Provider, h.Provider.GetClientConfiguration().GetClientID(), uuid.New().String()) }