From c195452bb03eb42a7358a5a59aec86dbe0aafd39 Mon Sep 17 00:00:00 2001 From: Livio Amstutz Date: Thu, 14 Apr 2022 10:10:56 +0200 Subject: [PATCH] feat(rp): provide key by data (not only path) for jwt profile (#168) --- example/client/app/app.go | 2 +- pkg/client/rp/relaying_party.go | 42 ++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/example/client/app/app.go b/example/client/app/app.go index 6db1597..e0369e3 100644 --- a/example/client/app/app.go +++ b/example/client/app/app.go @@ -40,7 +40,7 @@ func main() { options = append(options, rp.WithPKCE(cookieHandler)) } if keyPath != "" { - options = append(options, rp.WithClientKey(keyPath)) + options = append(options, rp.WithJWTProfile(rp.SignerFromKeyPath(keyPath))) } provider, err := rp.NewRelyingPartyOIDC(issuer, clientID, clientSecret, redirectURI, scopes, options...) diff --git a/pkg/client/rp/relaying_party.go b/pkg/client/rp/relaying_party.go index 98ab354..91622f3 100644 --- a/pkg/client/rp/relaying_party.go +++ b/pkg/client/rp/relaying_party.go @@ -233,14 +233,50 @@ func WithVerifierOpts(opts ...VerifierOption) Option { } } +// WithClientKey specifies the path to the key.json to be used for the JWT Profile Client Authentication on the token endpoint +// +//deprecated: use WithJWTProfile(SignerFromKeyPath(path)) instead func WithClientKey(path string) Option { + return WithJWTProfile(SignerFromKeyPath(path)) +} + +// WithJWTProfile creates a signer used for the JWT Profile Client Authentication on the token endpoint +func WithJWTProfile(signerFromKey SignerFromKey) Option { return func(rp *relyingParty) error { - config, err := client.ConfigFromKeyFile(path) + signer, err := signerFromKey() if err != nil { return err } - rp.signer, err = client.NewSignerFromPrivateKeyByte([]byte(config.Key), config.KeyID) - return err + rp.signer = signer + return nil + } +} + +type SignerFromKey func() (jose.Signer, error) + +func SignerFromKeyPath(path string) SignerFromKey { + return func() (jose.Signer, error) { + config, err := client.ConfigFromKeyFile(path) + if err != nil { + return nil, err + } + return client.NewSignerFromPrivateKeyByte([]byte(config.Key), config.KeyID) + } +} + +func SignerFromKeyFile(fileData []byte) SignerFromKey { + return func() (jose.Signer, error) { + config, err := client.ConfigFromKeyFileData(fileData) + if err != nil { + return nil, err + } + return client.NewSignerFromPrivateKeyByte([]byte(config.Key), config.KeyID) + } +} + +func SignerFromKeyAndKeyID(key []byte, keyID string) SignerFromKey { + return func() (jose.Signer, error) { + return client.NewSignerFromPrivateKeyByte(key, keyID) } }