custom claims for assertion and jwt profile request

This commit is contained in:
Livio Amstutz 2021-06-23 14:01:31 +02:00
parent e9fc710b1f
commit 0b446618c7
3 changed files with 207 additions and 25 deletions

View file

@ -14,22 +14,39 @@ import (
type JWTProfileVerifier interface {
oidc.Verifier
Storage() jwtProfileKeyStorage
CheckSubject(request *oidc.JWTTokenRequest) error
}
type jwtProfileVerifier struct {
storage jwtProfileKeyStorage
issuer string
maxAgeIAT time.Duration
offset time.Duration
storage jwtProfileKeyStorage
subjectCheck func(request *oidc.JWTTokenRequest) error
issuer string
maxAgeIAT time.Duration
offset time.Duration
}
//NewJWTProfileVerifier creates a oidc.Verifier for JWT Profile assertions (authorization grant and client authentication)
func NewJWTProfileVerifier(storage jwtProfileKeyStorage, issuer string, maxAgeIAT, offset time.Duration) JWTProfileVerifier {
return &jwtProfileVerifier{
storage: storage,
issuer: issuer,
maxAgeIAT: maxAgeIAT,
offset: offset,
func NewJWTProfileVerifier(storage jwtProfileKeyStorage, issuer string, maxAgeIAT, offset time.Duration, opts ...JWTProfileVerifierOption) JWTProfileVerifier {
j := &jwtProfileVerifier{
storage: storage,
subjectCheck: SubjectIsIssuer,
issuer: issuer,
maxAgeIAT: maxAgeIAT,
offset: offset,
}
for _, opt := range opts {
opt(j)
}
return j
}
type JWTProfileVerifierOption func(*jwtProfileVerifier)
func SubjectCheck(check func(request *oidc.JWTTokenRequest) error) JWTProfileVerifierOption {
return func(verifier *jwtProfileVerifier) {
verifier.subjectCheck = check
}
}
@ -49,6 +66,10 @@ func (v *jwtProfileVerifier) Offset() time.Duration {
return v.offset
}
func (v *jwtProfileVerifier) CheckSubject(request *oidc.JWTTokenRequest) error {
return v.subjectCheck(request)
}
//VerifyJWTAssertion verifies the assertion string from JWT Profile (authorization grant and client authentication)
//
//checks audience, exp, iat, signature and that issuer and sub are the same
@ -71,9 +92,8 @@ func VerifyJWTAssertion(ctx context.Context, assertion string, v JWTProfileVerif
return nil, err
}
if request.Issuer != request.Subject {
//TODO: implement delegation (openid core / oauth rfc)
return nil, errors.New("delegation not yet implemented, issuer and sub must be identical")
if err = v.CheckSubject(request); err != nil {
return nil, err
}
keySet := &jwtProfileKeySet{v.Storage(), request.Issuer}
@ -88,6 +108,13 @@ type jwtProfileKeyStorage interface {
GetKeyByIDAndUserID(ctx context.Context, keyID, userID string) (*jose.JSONWebKey, error)
}
func SubjectIsIssuer(request *oidc.JWTTokenRequest) error {
if request.Issuer != request.Subject {
return errors.New("delegation not allowed, issuer and sub must be identical")
}
return nil
}
type jwtProfileKeySet struct {
storage jwtProfileKeyStorage
userID string