harmonize jwtProfile and existing interfaces / functions
This commit is contained in:
parent
87b30dcd66
commit
a56a4a018a
14 changed files with 259 additions and 632 deletions
99
pkg/op/verifier_jwt_profile.go
Normal file
99
pkg/op/verifier_jwt_profile.go
Normal file
|
@ -0,0 +1,99 @@
|
|||
package op
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"gopkg.in/square/go-jose.v2"
|
||||
|
||||
"github.com/caos/oidc/pkg/oidc"
|
||||
)
|
||||
|
||||
type JWTProfileVerifier interface {
|
||||
oidc.Verifier
|
||||
Storage() Storage
|
||||
}
|
||||
|
||||
type jwtProfileVerifier struct {
|
||||
storage Storage
|
||||
issuer string
|
||||
}
|
||||
|
||||
func NewJWTProfileVerifier(storage Storage, issuer string) JWTProfileVerifier {
|
||||
return &jwtProfileVerifier{
|
||||
storage: storage,
|
||||
issuer: issuer,
|
||||
}
|
||||
}
|
||||
|
||||
func (v *jwtProfileVerifier) Issuer() string {
|
||||
return v.issuer
|
||||
}
|
||||
|
||||
func (v *jwtProfileVerifier) Storage() Storage {
|
||||
return v.storage
|
||||
}
|
||||
|
||||
func (v *jwtProfileVerifier) MaxAgeIAT() time.Duration {
|
||||
//TODO: define in conf/opts
|
||||
return 1 * time.Hour
|
||||
}
|
||||
|
||||
func (v *jwtProfileVerifier) Offset() time.Duration {
|
||||
//TODO: define in conf/opts
|
||||
return time.Second
|
||||
}
|
||||
|
||||
func VerifyJWTAssertion(ctx context.Context, assertion string, v JWTProfileVerifier) (*oidc.JWTTokenRequest, error) {
|
||||
request := new(oidc.JWTTokenRequest)
|
||||
payload, err := oidc.ParseToken(assertion, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = oidc.CheckAudience(request, v.Issuer()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = oidc.CheckExpiration(request, v.Offset()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = oidc.CheckIssuedAt(request, v.MaxAgeIAT(), v.Offset()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if request.Issuer != request.Subject {
|
||||
//TODO: implement delegation (openid core / oauth rfc)
|
||||
}
|
||||
|
||||
keySet := &jwtProfileKeySet{v.Storage(), request.Subject}
|
||||
|
||||
if err = oidc.CheckSignature(ctx, assertion, payload, request, nil, keySet); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return request, nil
|
||||
}
|
||||
|
||||
type jwtProfileKeySet struct {
|
||||
Storage
|
||||
userID string
|
||||
}
|
||||
|
||||
func (k *jwtProfileKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) (payload []byte, err error) {
|
||||
keyID := ""
|
||||
for _, sig := range jws.Signatures {
|
||||
keyID = sig.Header.KeyID
|
||||
break
|
||||
}
|
||||
key, err := k.Storage.GetKeyByIDAndUserID(ctx, keyID, k.userID)
|
||||
if err != nil {
|
||||
return nil, errors.New("error fetching keys")
|
||||
}
|
||||
payload, err, ok := oidc.CheckKey(keyID, jws, *key)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid kid")
|
||||
}
|
||||
return payload, err
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue