fix: handle single aud
string claim, extract en/decoder interface, comments (#51)
* en/decoding abstraction * some comments * fix token validation and error messages * fix: audience mapping (single aud string) * fix tests with VerifyIdToken * reformat imports * go mod tidy * Update pkg/oidc/authorization.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update pkg/oidc/authorization.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update pkg/op/authrequest_test.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * fix capitalization Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
parent
822ffb581f
commit
abd3b6f521
24 changed files with 381 additions and 139 deletions
|
@ -158,14 +158,8 @@ func (v *DefaultVerifier) Verify(ctx context.Context, accessToken, idTokenString
|
|||
return idToken, nil
|
||||
}
|
||||
|
||||
func (v *DefaultVerifier) now() time.Time {
|
||||
if v.config.now.IsZero() {
|
||||
v.config.now = time.Now().UTC().Round(time.Second)
|
||||
}
|
||||
return v.config.now
|
||||
}
|
||||
|
||||
//VerifyIDToken: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
|
||||
//Verify implements the `VerifyIDToken` method of the `Verifier` interface
|
||||
//according to https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
|
||||
func (v *DefaultVerifier) VerifyIDToken(ctx context.Context, idTokenString string) (*oidc.IDTokenClaims, error) {
|
||||
//1. if encrypted --> decrypt
|
||||
decrypted, err := v.decryptToken(idTokenString)
|
||||
|
@ -227,6 +221,13 @@ func (v *DefaultVerifier) VerifyIDToken(ctx context.Context, idTokenString strin
|
|||
return claims, nil
|
||||
}
|
||||
|
||||
func (v *DefaultVerifier) now() time.Time {
|
||||
if v.config.now.IsZero() {
|
||||
v.config.now = time.Now().UTC().Round(time.Second)
|
||||
}
|
||||
return v.config.now
|
||||
}
|
||||
|
||||
func (v *DefaultVerifier) parseToken(tokenString string) (*oidc.IDTokenClaims, []byte, error) {
|
||||
parts := strings.Split(tokenString, ".")
|
||||
if len(parts) != 3 {
|
||||
|
@ -372,7 +373,7 @@ func (v *DefaultVerifier) decryptToken(tokenString string) (string, error) {
|
|||
}
|
||||
|
||||
func (v *DefaultVerifier) verifyAccessToken(accessToken, atHash string, sigAlgorithm jose.SignatureAlgorithm) error {
|
||||
if accessToken == "" {
|
||||
if atHash == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
3
pkg/rp/mock/generate.go
Normal file
3
pkg/rp/mock/generate.go
Normal file
|
@ -0,0 +1,3 @@
|
|||
package mock
|
||||
|
||||
//go:generate mockgen -package mock -destination ./verifier.mock.go github.com/caos/oidc/pkg/rp Verifier
|
65
pkg/rp/mock/verifier.mock.go
Normal file
65
pkg/rp/mock/verifier.mock.go
Normal file
|
@ -0,0 +1,65 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/caos/oidc/pkg/rp (interfaces: Verifier)
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
|
||||
import (
|
||||
context "context"
|
||||
oidc "github.com/caos/oidc/pkg/oidc"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockVerifier is a mock of Verifier interface
|
||||
type MockVerifier struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockVerifierMockRecorder
|
||||
}
|
||||
|
||||
// MockVerifierMockRecorder is the mock recorder for MockVerifier
|
||||
type MockVerifierMockRecorder struct {
|
||||
mock *MockVerifier
|
||||
}
|
||||
|
||||
// NewMockVerifier creates a new mock instance
|
||||
func NewMockVerifier(ctrl *gomock.Controller) *MockVerifier {
|
||||
mock := &MockVerifier{ctrl: ctrl}
|
||||
mock.recorder = &MockVerifierMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockVerifier) EXPECT() *MockVerifierMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Verify mocks base method
|
||||
func (m *MockVerifier) Verify(arg0 context.Context, arg1, arg2 string) (*oidc.IDTokenClaims, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Verify", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(*oidc.IDTokenClaims)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Verify indicates an expected call of Verify
|
||||
func (mr *MockVerifierMockRecorder) Verify(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Verify", reflect.TypeOf((*MockVerifier)(nil).Verify), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// VerifyIDToken mocks base method
|
||||
func (m *MockVerifier) VerifyIDToken(arg0 context.Context, arg1 string) (*oidc.IDTokenClaims, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "VerifyIDToken", arg0, arg1)
|
||||
ret0, _ := ret[0].(*oidc.IDTokenClaims)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// VerifyIDToken indicates an expected call of VerifyIDToken
|
||||
func (mr *MockVerifierMockRecorder) VerifyIDToken(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyIDToken", reflect.TypeOf((*MockVerifier)(nil).VerifyIDToken), arg0, arg1)
|
||||
}
|
37
pkg/rp/mock/verifier.mock.impl.go
Normal file
37
pkg/rp/mock/verifier.mock.impl.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
package mock
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
|
||||
"github.com/caos/oidc/pkg/oidc"
|
||||
"github.com/caos/oidc/pkg/rp"
|
||||
)
|
||||
|
||||
func NewVerifier(t *testing.T) rp.Verifier {
|
||||
return NewMockVerifier(gomock.NewController(t))
|
||||
}
|
||||
|
||||
func NewMockVerifierExpectInvalid(t *testing.T) rp.Verifier {
|
||||
m := NewVerifier(t)
|
||||
ExpectVerifyInvalid(m)
|
||||
return m
|
||||
}
|
||||
|
||||
func ExpectVerifyInvalid(v rp.Verifier) {
|
||||
mock := v.(*MockVerifier)
|
||||
mock.EXPECT().VerifyIDToken(gomock.Any(), gomock.Any()).Return(nil, errors.New("invalid"))
|
||||
}
|
||||
|
||||
func NewMockVerifierExpectValid(t *testing.T) rp.Verifier {
|
||||
m := NewVerifier(t)
|
||||
ExpectVerifyValid(m)
|
||||
return m
|
||||
}
|
||||
|
||||
func ExpectVerifyValid(v rp.Verifier) {
|
||||
mock := v.(*MockVerifier)
|
||||
mock.EXPECT().VerifyIDToken(gomock.Any(), gomock.Any()).Return(&oidc.IDTokenClaims{Userinfo: oidc.Userinfo{Subject: "id"}}, nil)
|
||||
}
|
|
@ -12,4 +12,7 @@ type Verifier interface {
|
|||
|
||||
//Verify checks the access_token and id_token and returns the `id token claims`
|
||||
Verify(ctx context.Context, accessToken, idTokenString string) (*oidc.IDTokenClaims, error)
|
||||
|
||||
//VerifyIDToken checks the id_token only and returns its `id token claims`
|
||||
VerifyIDToken(ctx context.Context, idTokenString string) (*oidc.IDTokenClaims, error)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue