diff --git a/pkg/op/authrequest.go b/pkg/op/authrequest.go index aa8a36c..cf40e62 100644 --- a/pkg/op/authrequest.go +++ b/pkg/op/authrequest.go @@ -17,7 +17,7 @@ type Authorizer interface { Decoder() utils.Decoder Encoder() utils.Encoder Signer() Signer - IDTokenVerifier() IDTokenHintVerifier + IDTokenHintVerifier() IDTokenHintVerifier Crypto() Crypto Issuer() string } @@ -29,12 +29,6 @@ type AuthorizeValidator interface { ValidateAuthRequest(context.Context, *oidc.AuthRequest, Storage, IDTokenHintVerifier) (string, error) } -//ValidationAuthorizer is an extension of Authorizer interface -//implementing it's own validation mechanism for the auth request -// -//Deprecated: ValidationAuthorizer exists for historical compatibility. Use ValidationAuthorizer itself -type ValidationAuthorizer AuthorizeValidator - func authorizeHandler(authorizer Authorizer) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { Authorize(w, r, authorizer) @@ -59,7 +53,7 @@ func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer) { if validater, ok := authorizer.(AuthorizeValidator); ok { validation = validater.ValidateAuthRequest } - userID, err := validation(r.Context(), authReq, authorizer.Storage(), authorizer.IDTokenVerifier()) + userID, err := validation(r.Context(), authReq, authorizer.Storage(), authorizer.IDTokenHintVerifier()) if err != nil { AuthRequestError(w, r, authReq, err, authorizer.Encoder()) return @@ -204,14 +198,14 @@ func AuthorizeCallback(w http.ResponseWriter, r *http.Request, authorizer Author func AuthResponse(authReq AuthRequest, authorizer Authorizer, w http.ResponseWriter, r *http.Request) { client, err := authorizer.Storage().GetClientByClientID(r.Context(), authReq.GetClientID()) if err != nil { - + AuthRequestError(w, r, authReq, err, authorizer.Encoder()) + return } if authReq.GetResponseType() == oidc.ResponseTypeCode { AuthResponseCode(w, r, authReq, authorizer) return } AuthResponseToken(w, r, authReq, authorizer, client) - return } //AuthResponseCode creates the successful code authentication response diff --git a/pkg/op/client.go b/pkg/op/client.go index ef9b62e..3184b90 100644 --- a/pkg/op/client.go +++ b/pkg/op/client.go @@ -15,6 +15,12 @@ const ( AccessTokenTypeJWT ) +type ApplicationType int + +type AuthMethod string + +type AccessTokenType int + type Client interface { GetID() string RedirectURIs() []string @@ -28,10 +34,6 @@ type Client interface { DevMode() bool } -func IsConfidentialType(c Client) bool { - return c.ApplicationType() == ApplicationTypeWeb -} - func ContainsResponseType(types []oidc.ResponseType, responseType oidc.ResponseType) bool { for _, t := range types { if t == responseType { @@ -41,8 +43,6 @@ func ContainsResponseType(types []oidc.ResponseType, responseType oidc.ResponseT return false } -type ApplicationType int - -type AuthMethod string - -type AccessTokenType int +func IsConfidentialType(c Client) bool { + return c.ApplicationType() == ApplicationTypeWeb +} diff --git a/pkg/op/default_op.go b/pkg/op/default_op.go deleted file mode 100644 index 374cfb7..0000000 --- a/pkg/op/default_op.go +++ /dev/null @@ -1,361 +0,0 @@ -package op - -import ( - "context" - "errors" - "net/http" - "time" - - "github.com/gorilla/schema" - "gopkg.in/square/go-jose.v2" - - "github.com/caos/logging" - - "github.com/caos/oidc/pkg/oidc" - "github.com/caos/oidc/pkg/rp" - "github.com/caos/oidc/pkg/utils" -) - -const ( - defaultAuthorizationEndpoint = "authorize" - defaulTokenEndpoint = "oauth/token" - defaultIntrospectEndpoint = "introspect" - defaultUserinfoEndpoint = "userinfo" - defaultEndSessionEndpoint = "end_session" - defaultKeysEndpoint = "keys" - - AuthMethodBasic AuthMethod = "client_secret_basic" - AuthMethodPost = "client_secret_post" - AuthMethodNone = "none" - - CodeMethodS256 = "S256" -) - -var ( - DefaultEndpoints = &endpoints{ - Authorization: NewEndpoint(defaultAuthorizationEndpoint), - Token: NewEndpoint(defaulTokenEndpoint), - Introspection: NewEndpoint(defaultIntrospectEndpoint), - Userinfo: NewEndpoint(defaultUserinfoEndpoint), - EndSession: NewEndpoint(defaultEndSessionEndpoint), - JwksURI: NewEndpoint(defaultKeysEndpoint), - } -) - -type DefaultOP struct { - config *Config - endpoints *endpoints - storage Storage - signer Signer - verifier IDTokenHintVerifier - crypto Crypto - http http.Handler - decoder *schema.Decoder - encoder *schema.Encoder - interceptors []HttpInterceptor - retry func(int) (bool, int) - timer <-chan time.Time -} - -type Config struct { - Issuer string - CryptoKey [32]byte - DefaultLogoutRedirectURI string - CodeMethodS256 bool - // ScopesSupported: oidc.SupportedScopes, - // ResponseTypesSupported: responseTypes, - // GrantTypesSupported: oidc.SupportedGrantTypes, - // ClaimsSupported: oidc.SupportedClaims, - // IdTokenSigningAlgValuesSupported: []string{keys.SigningAlgorithm}, - // SubjectTypesSupported: []string{"public"}, - // TokenEndpointAuthMethodsSupported: -} - -type endpoints struct { - Authorization Endpoint - Token Endpoint - Introspection Endpoint - Userinfo Endpoint - EndSession Endpoint - CheckSessionIframe Endpoint - JwksURI Endpoint -} - -type DefaultOPOpts func(o *DefaultOP) error - -func WithCustomAuthEndpoint(endpoint Endpoint) DefaultOPOpts { - return func(o *DefaultOP) error { - if err := endpoint.Validate(); err != nil { - return err - } - o.endpoints.Authorization = endpoint - return nil - } -} - -func WithCustomTokenEndpoint(endpoint Endpoint) DefaultOPOpts { - return func(o *DefaultOP) error { - if err := endpoint.Validate(); err != nil { - return err - } - o.endpoints.Token = endpoint - return nil - } -} - -func WithCustomUserinfoEndpoint(endpoint Endpoint) DefaultOPOpts { - return func(o *DefaultOP) error { - if err := endpoint.Validate(); err != nil { - return err - } - o.endpoints.Userinfo = endpoint - return nil - } -} - -func WithCustomEndSessionEndpoint(endpoint Endpoint) DefaultOPOpts { - return func(o *DefaultOP) error { - if err := endpoint.Validate(); err != nil { - return err - } - o.endpoints.EndSession = endpoint - return nil - } -} - -func WithCustomKeysEndpoint(endpoint Endpoint) DefaultOPOpts { - return func(o *DefaultOP) error { - if err := endpoint.Validate(); err != nil { - return err - } - o.endpoints.JwksURI = endpoint - return nil - } -} - -func WithHttpInterceptors(interceptors ...HttpInterceptor) DefaultOPOpts { - return func(o *DefaultOP) error { - o.interceptors = append(o.interceptors, interceptors...) - return nil - } -} - -func WithRetry(max int, sleep time.Duration) DefaultOPOpts { - return func(o *DefaultOP) error { - o.retry = func(count int) (bool, int) { - count++ - if count == max { - return false, count - } - time.Sleep(sleep) - return true, count - } - return nil - } -} - -func WithTimer(timer <-chan time.Time) DefaultOPOpts { - return func(o *DefaultOP) error { - o.timer = timer - return nil - } -} - -func NewDefaultOP(ctx context.Context, config *Config, storage Storage, opOpts ...DefaultOPOpts) (OpenIDProvider, error) { - err := ValidateIssuer(config.Issuer) - if err != nil { - return nil, err - } - - p := &DefaultOP{ - config: config, - storage: storage, - endpoints: DefaultEndpoints, - timer: make(<-chan time.Time), - } - - for _, optFunc := range opOpts { - if err := optFunc(p); err != nil { - return nil, err - } - } - - keyCh := make(chan jose.SigningKey) - p.signer = NewDefaultSigner(ctx, storage, keyCh) - go p.ensureKey(ctx, storage, keyCh, p.timer) - - p.verifier = NewIDTokenHintVerifier(config.Issuer, p) - - p.http = CreateRouter(p, p.interceptors...) - - p.decoder = schema.NewDecoder() - p.decoder.IgnoreUnknownKeys(true) - - p.encoder = schema.NewEncoder() - - p.crypto = NewAESCrypto(config.CryptoKey) - - return p, nil -} - -func (p *DefaultOP) Issuer() string { - return p.config.Issuer -} - -func (p *DefaultOP) AuthorizationEndpoint() Endpoint { - return p.endpoints.Authorization -} - -func (p *DefaultOP) TokenEndpoint() Endpoint { - return Endpoint(p.endpoints.Token) -} - -func (p *DefaultOP) UserinfoEndpoint() Endpoint { - return Endpoint(p.endpoints.Userinfo) -} - -func (p *DefaultOP) EndSessionEndpoint() Endpoint { - return Endpoint(p.endpoints.EndSession) -} - -func (p *DefaultOP) KeysEndpoint() Endpoint { - return Endpoint(p.endpoints.JwksURI) -} - -func (p *DefaultOP) AuthMethodPostSupported() bool { - return true //TODO: config -} - -func (p *DefaultOP) CodeMethodS256Supported() bool { - return p.config.CodeMethodS256 -} - -func (p *DefaultOP) HttpHandler() http.Handler { - return p.http -} - -func (p *DefaultOP) HandleDiscovery(w http.ResponseWriter, r *http.Request) { - Discover(w, CreateDiscoveryConfig(p, p.Signer())) -} - -func (p *DefaultOP) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) { - keyID := "" - for _, sig := range jws.Signatures { - keyID = sig.Header.KeyID - break - } - keySet, err := p.Storage().GetKeySet(ctx) - if err != nil { - return nil, errors.New("error fetching keys") - } - payload, err, ok := rp.CheckKey(keyID, keySet.Keys, jws) - if !ok { - return nil, errors.New("invalid kid") - } - return payload, err -} - -func (p *DefaultOP) Decoder() utils.Decoder { - return p.decoder -} - -func (p *DefaultOP) Encoder() utils.Encoder { - return p.encoder -} - -func (p *DefaultOP) Storage() Storage { - return p.storage -} - -func (p *DefaultOP) Signer() Signer { - return p.signer -} - -func (p *DefaultOP) Crypto() Crypto { - return p.crypto -} - -func (p *DefaultOP) ClientJWTVerifier() oidc.Verifier { - return p.verifier -} - -func (p *DefaultOP) Probes() []ProbesFn { - return []ProbesFn{ - ReadySigner(p.Signer()), - ReadyStorage(p.Storage()), - } -} - -func (p *DefaultOP) HandleKeys(w http.ResponseWriter, r *http.Request) { - Keys(w, r, p) -} - -func (p *DefaultOP) HandleAuthorize(w http.ResponseWriter, r *http.Request) { - Authorize(w, r, p) -} - -func (p *DefaultOP) HandleAuthorizeCallback(w http.ResponseWriter, r *http.Request) { - AuthorizeCallback(w, r, p) -} - -func (p *DefaultOP) HandleExchange(w http.ResponseWriter, r *http.Request) { - reqType := r.FormValue("grant_type") - if reqType == "" { - RequestError(w, r, ErrInvalidRequest("grant_type missing")) - return - } - switch reqType { - case string(oidc.GrantTypeCode): - CodeExchange(w, r, p) - return - case string(oidc.GrantTypeBearer): - JWTExchange(w, r, p) - return - } - TokenExchange(w, r, p) -} - -func (p *DefaultOP) HandleUserinfo(w http.ResponseWriter, r *http.Request) { - Userinfo(w, r, p) -} - -func (p *DefaultOP) HandleEndSession(w http.ResponseWriter, r *http.Request) { - EndSession(w, r, p) -} - -func (p *DefaultOP) DefaultLogoutRedirectURI() string { - return p.config.DefaultLogoutRedirectURI -} -func (p *DefaultOP) IDTokenVerifier() IDTokenHintVerifier { - return p.verifier -} - -func (p *DefaultOP) ensureKey(ctx context.Context, storage Storage, keyCh chan<- jose.SigningKey, timer <-chan time.Time) { - count := 0 - timer = time.After(0) - errCh := make(chan error) - go storage.GetSigningKey(ctx, keyCh, errCh, timer) - for { - select { - case <-ctx.Done(): - return - case err := <-errCh: - if err == nil { - continue - } - _, ok := err.(StorageNotFoundError) - if ok { - err := storage.SaveNewKeyPair(ctx) - if err == nil { - continue - } - } - ok, count = p.retry(count) - if ok { - timer = time.After(0) - continue - } - logging.Log("OP-n6ynVE").WithError(err).Panic("error in key signer") - } - } -} diff --git a/pkg/op/discovery.go b/pkg/op/discovery.go index 5461cfa..3ec7631 100644 --- a/pkg/op/discovery.go +++ b/pkg/op/discovery.go @@ -38,20 +38,12 @@ func CreateDiscoveryConfig(c Configuration, s Signer) *oidc.DiscoveryConfigurati } } -const ( - ScopeOpenID = "openid" - ScopeProfile = "profile" - ScopeEmail = "email" - ScopePhone = "phone" - ScopeAddress = "address" -) - var DefaultSupportedScopes = []string{ - ScopeOpenID, - ScopeProfile, - ScopeEmail, - ScopePhone, - ScopeAddress, + oidc.ScopeOpenID, + oidc.ScopeProfile, + oidc.ScopeEmail, + oidc.ScopePhone, + oidc.ScopeAddress, } func Scopes(c Configuration) []string { diff --git a/pkg/op/verifier.go b/pkg/op/id_token_hint_verifier.go similarity index 100% rename from pkg/op/verifier.go rename to pkg/op/id_token_hint_verifier.go diff --git a/pkg/op/keys.go b/pkg/op/keys.go index ba4d41d..4b8d607 100644 --- a/pkg/op/keys.go +++ b/pkg/op/keys.go @@ -19,7 +19,9 @@ func keysHandler(k KeyProvider) func(http.ResponseWriter, *http.Request) { func Keys(w http.ResponseWriter, r *http.Request, k KeyProvider) { keySet, err := k.Storage().GetKeySet(r.Context()) if err != nil { - + w.WriteHeader(http.StatusInternalServerError) + utils.MarshalJSON(w, err) + return } utils.MarshalJSON(w, keySet) } diff --git a/pkg/op/op.go b/pkg/op/op.go index 0d6f019..0bad929 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -1,18 +1,48 @@ package op import ( + "context" + "errors" "net/http" + "time" + "github.com/caos/logging" "github.com/gorilla/handlers" "github.com/gorilla/mux" + "github.com/gorilla/schema" + "gopkg.in/square/go-jose.v2" "github.com/caos/oidc/pkg/oidc" + "github.com/caos/oidc/pkg/rp" "github.com/caos/oidc/pkg/utils" ) const ( - healthzEndpoint = "/healthz" - readinessEndpoint = "/ready" + healthzEndpoint = "/healthz" + readinessEndpoint = "/ready" + defaultAuthorizationEndpoint = "authorize" + defaulTokenEndpoint = "oauth/token" + defaultIntrospectEndpoint = "introspect" + defaultUserinfoEndpoint = "userinfo" + defaultEndSessionEndpoint = "end_session" + defaultKeysEndpoint = "keys" + + AuthMethodBasic AuthMethod = "client_secret_basic" + AuthMethodPost AuthMethod = "client_secret_post" + AuthMethodNone AuthMethod = "none" + + CodeMethodS256 = "S256" +) + +var ( + DefaultEndpoints = &endpoints{ + Authorization: NewEndpoint(defaultAuthorizationEndpoint), + Token: NewEndpoint(defaulTokenEndpoint), + Introspection: NewEndpoint(defaultIntrospectEndpoint), + Userinfo: NewEndpoint(defaultUserinfoEndpoint), + EndSession: NewEndpoint(defaultEndSessionEndpoint), + JwksURI: NewEndpoint(defaultKeysEndpoint), + } ) type OpenIDProvider interface { @@ -20,7 +50,7 @@ type OpenIDProvider interface { Storage() Storage Decoder() utils.Decoder Encoder() utils.Encoder - IDTokenVerifier() IDTokenHintVerifier + IDTokenHintVerifier() IDTokenHintVerifier Crypto() Crypto DefaultLogoutRedirectURI() string Signer() Signer @@ -54,6 +84,293 @@ func CreateRouter(o OpenIDProvider, interceptors ...HttpInterceptor) *mux.Router return router } +type Config struct { + Issuer string + CryptoKey [32]byte + DefaultLogoutRedirectURI string + CodeMethodS256 bool + // ScopesSupported: oidc.SupportedScopes, + // ResponseTypesSupported: responseTypes, + // GrantTypesSupported: oidc.SupportedGrantTypes, + // ClaimsSupported: oidc.SupportedClaims, + // IdTokenSigningAlgValuesSupported: []string{keys.SigningAlgorithm}, + // SubjectTypesSupported: []string{"public"}, + // TokenEndpointAuthMethodsSupported: +} + +type endpoints struct { + Authorization Endpoint + Token Endpoint + Introspection Endpoint + Userinfo Endpoint + EndSession Endpoint + CheckSessionIframe Endpoint + JwksURI Endpoint +} + +func NewOpenIDProvider(ctx context.Context, config *Config, storage Storage, opOpts ...Option) (OpenIDProvider, error) { + err := ValidateIssuer(config.Issuer) + if err != nil { + return nil, err + } + + o := &openidProvider{ + config: config, + storage: storage, + endpoints: DefaultEndpoints, + timer: make(<-chan time.Time), + } + + for _, optFunc := range opOpts { + if err := optFunc(o); err != nil { + return nil, err + } + } + + keyCh := make(chan jose.SigningKey) + o.signer = NewDefaultSigner(ctx, storage, keyCh) + go EnsureKey(ctx, storage, keyCh, o.timer, o.retry) + + o.idTokenHintVerifier = NewIDTokenHintVerifier(config.Issuer, o) + + o.httpHandler = CreateRouter(o, o.interceptors...) + + o.decoder = schema.NewDecoder() + o.decoder.IgnoreUnknownKeys(true) + + o.encoder = schema.NewEncoder() + + o.crypto = NewAESCrypto(config.CryptoKey) + + return o, nil +} + +type openidProvider struct { + config *Config + endpoints *endpoints + storage Storage + signer Signer + idTokenHintVerifier IDTokenHintVerifier + crypto Crypto + httpHandler http.Handler + decoder *schema.Decoder + encoder *schema.Encoder + interceptors []HttpInterceptor + retry func(int) (bool, int) + timer <-chan time.Time +} + +func (o *openidProvider) Issuer() string { + return o.config.Issuer +} + +func (o *openidProvider) AuthorizationEndpoint() Endpoint { + return o.endpoints.Authorization +} + +func (o *openidProvider) TokenEndpoint() Endpoint { + return o.endpoints.Token +} + +func (o *openidProvider) UserinfoEndpoint() Endpoint { + return o.endpoints.Userinfo +} + +func (o *openidProvider) EndSessionEndpoint() Endpoint { + return o.endpoints.EndSession +} + +func (o *openidProvider) KeysEndpoint() Endpoint { + return o.endpoints.JwksURI +} + +func (o *openidProvider) AuthMethodPostSupported() bool { + return true //todo: config +} + +func (o *openidProvider) CodeMethodS256Supported() bool { + return o.config.CodeMethodS256 +} + +func (o *openidProvider) Storage() Storage { + return o.storage +} + +func (o *openidProvider) Decoder() utils.Decoder { + return o.decoder +} + +func (o *openidProvider) Encoder() utils.Encoder { + return o.encoder +} + +func (o *openidProvider) IDTokenHintVerifier() IDTokenHintVerifier { + return o.idTokenHintVerifier +} + +func (o *openidProvider) Crypto() Crypto { + return o.crypto +} + +func (o *openidProvider) DefaultLogoutRedirectURI() string { + return o.config.DefaultLogoutRedirectURI +} + +func (o *openidProvider) Signer() Signer { + return o.signer +} + +func (o *openidProvider) Probes() []ProbesFn { + return []ProbesFn{ + ReadySigner(o.Signer()), + ReadyStorage(o.Storage()), + } +} + +func (o *openidProvider) HttpHandler() http.Handler { + return o.httpHandler +} + +//VerifySignature implements the oidc.KeySet interface +//providing an implementation for the keys stored in the OP Storage interface +func (o *openidProvider) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) { + keyID := "" + for _, sig := range jws.Signatures { + keyID = sig.Header.KeyID + break + } + keySet, err := o.Storage().GetKeySet(ctx) + if err != nil { + return nil, errors.New("error fetching keys") + } + payload, err, ok := rp.CheckKey(keyID, keySet.Keys, jws) + if !ok { + return nil, errors.New("invalid kid") + } + return payload, err +} + +func EnsureKey(ctx context.Context, storage Storage, keyCh chan<- jose.SigningKey, timer <-chan time.Time, retry func(int) (bool, int)) { + count := 0 + timer = time.After(0) + errCh := make(chan error) + go storage.GetSigningKey(ctx, keyCh, errCh, timer) + for { + select { + case <-ctx.Done(): + return + case err := <-errCh: + if err == nil { + continue + } + _, ok := err.(StorageNotFoundError) + if ok { + err := storage.SaveNewKeyPair(ctx) + if err == nil { + continue + } + } + ok, count = retry(count) + if ok { + timer = time.After(0) + continue + } + logging.Log("OP-n6ynVE").WithError(err).Panic("error in key signer") + } + } +} + +type Option func(o *openidProvider) error + +func WithCustomAuthEndpoint(endpoint Endpoint) Option { + return func(o *openidProvider) error { + if err := endpoint.Validate(); err != nil { + return err + } + o.endpoints.Authorization = endpoint + return nil + } +} + +func WithCustomTokenEndpoint(endpoint Endpoint) Option { + return func(o *openidProvider) error { + if err := endpoint.Validate(); err != nil { + return err + } + o.endpoints.Token = endpoint + return nil + } +} + +func WithCustomUserinfoEndpoint(endpoint Endpoint) Option { + return func(o *openidProvider) error { + if err := endpoint.Validate(); err != nil { + return err + } + o.endpoints.Userinfo = endpoint + return nil + } +} + +func WithCustomEndSessionEndpoint(endpoint Endpoint) Option { + return func(o *openidProvider) error { + if err := endpoint.Validate(); err != nil { + return err + } + o.endpoints.EndSession = endpoint + return nil + } +} + +func WithCustomKeysEndpoint(endpoint Endpoint) Option { + return func(o *openidProvider) error { + if err := endpoint.Validate(); err != nil { + return err + } + o.endpoints.JwksURI = endpoint + return nil + } +} + +func WithCustomEndpoints(auth, token, userInfo, endSession, keys Endpoint) Option { + return func(o *openidProvider) error { + o.endpoints.Authorization = auth + o.endpoints.Token = token + o.endpoints.Userinfo = userInfo + o.endpoints.EndSession = endSession + o.endpoints.JwksURI = keys + return nil + } +} + +func WithHttpInterceptors(interceptors ...HttpInterceptor) Option { + return func(o *openidProvider) error { + o.interceptors = append(o.interceptors, interceptors...) + return nil + } +} + +func WithRetry(max int, sleep time.Duration) Option { + return func(o *openidProvider) error { + o.retry = func(count int) (bool, int) { + count++ + if count == max { + return false, count + } + time.Sleep(sleep) + return true, count + } + return nil + } +} + +func WithTimer(timer <-chan time.Time) Option { + return func(o *openidProvider) error { + o.timer = timer + return nil + } +} + func buildInterceptor(interceptors ...HttpInterceptor) func(http.HandlerFunc) http.Handler { return func(handlerFunc http.HandlerFunc) http.Handler { handler := handlerFuncToHandler(handlerFunc) diff --git a/pkg/op/session.go b/pkg/op/session.go index 5a3936a..d04e361 100644 --- a/pkg/op/session.go +++ b/pkg/op/session.go @@ -11,7 +11,7 @@ import ( type SessionEnder interface { Decoder() utils.Decoder Storage() Storage - IDTokenVerifier() IDTokenHintVerifier + IDTokenHintVerifier() IDTokenHintVerifier DefaultLogoutRedirectURI() string } @@ -62,7 +62,7 @@ func ValidateEndSessionRequest(ctx context.Context, req *oidc.EndSessionRequest, if req.IdTokenHint == "" { return session, nil } - claims, err := VerifyIDTokenHint(ctx, req.IdTokenHint, ender.IDTokenVerifier()) + claims, err := VerifyIDTokenHint(ctx, req.IdTokenHint, ender.IDTokenHintVerifier()) if err != nil { return nil, ErrInvalidRequest("id_token_hint invalid") } diff --git a/pkg/op/token.go b/pkg/op/token.go index 10c8519..7fc95f5 100644 --- a/pkg/op/token.go +++ b/pkg/op/token.go @@ -102,7 +102,7 @@ func CreateIDToken(ctx context.Context, issuer string, authReq AuthRequest, vali exp := time.Now().UTC().Add(validity) userinfo, err := storage.GetUserinfoFromScopes(ctx, authReq.GetSubject(), authReq.GetScopes()) if err != nil { - + return "", err } claims := &oidc.IDTokenClaims{ Issuer: issuer, diff --git a/pkg/rp/relaying_party.go b/pkg/rp/relaying_party.go index 0192a35..8b98d06 100644 --- a/pkg/rp/relaying_party.go +++ b/pkg/rp/relaying_party.go @@ -155,6 +155,7 @@ func NewRelayingParty(config *Configuration, options ...Option) (RelayingParty, return nil, err } rp.oauthConfig.Endpoint = endpoints.Endpoint + rp.endpoints = endpoints } if rp.errorHandler == nil { diff --git a/pkg/rp/verifier.go b/pkg/rp/verifier.go index 3545cf6..d079b53 100644 --- a/pkg/rp/verifier.go +++ b/pkg/rp/verifier.go @@ -109,6 +109,9 @@ func NewIDTokenVerifier(issuer, clientID string, keySet oidc.KeySet) IDTokenVeri clientID: clientID, keySet: keySet, offset: 5 * time.Second, + nonce: func(_ context.Context) string { + return "" + }, } }