mirror of
https://github.com/nais/wonderwall.git
synced 2026-05-19 06:46:36 +00:00
add: session management check to get session_state from OP response, generate a externalSessionID if none supported.
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user