@@ -10,6 +10,7 @@ package jwt
10
10
11
11
import (
12
12
"context"
13
+ "crypto/rsa"
13
14
"encoding/json"
14
15
"fmt"
15
16
"io"
@@ -48,6 +49,11 @@ type Config struct {
48
49
//
49
50
PrivateKey []byte
50
51
52
+ // SignerProvider is a function that is used to create a Signer from the
53
+ // PrivateKeyID which is then used to sign JWT payloads. This takes
54
+ // precedence over default signer using the PrivateKey.
55
+ SignerProvider func (privateKeyID string ) (Signer , error )
56
+
51
57
// PrivateKeyID contains an optional hint indicating which key is being
52
58
// used.
53
59
PrivateKeyID string
@@ -101,10 +107,6 @@ type jwtSource struct {
101
107
}
102
108
103
109
func (js jwtSource ) Token () (* oauth2.Token , error ) {
104
- pk , err := internal .ParseKey (js .conf .PrivateKey )
105
- if err != nil {
106
- return nil , err
107
- }
108
110
hc := oauth2 .NewClient (js .ctx , nil )
109
111
claimSet := & jws.ClaimSet {
110
112
Iss : js .conf .Email ,
@@ -126,7 +128,23 @@ func (js jwtSource) Token() (*oauth2.Token, error) {
126
128
}
127
129
h := * defaultHeader
128
130
h .KeyID = js .conf .PrivateKeyID
129
- payload , err := jws .Encode (& h , claimSet , pk )
131
+ var err error
132
+ payload := ""
133
+ if js .conf .SignerProvider == nil {
134
+ var pk * rsa.PrivateKey
135
+ pk , err = internal .ParseKey (js .conf .PrivateKey )
136
+ if err != nil {
137
+ return nil , err
138
+ }
139
+ payload , err = jws .Encode (& h , claimSet , pk )
140
+ } else {
141
+ var signer jws.Signer
142
+ signer , err = js .conf .SignerProvider (h .KeyID )
143
+ if err != nil {
144
+ return nil , err
145
+ }
146
+ payload , err = jws .EncodeWithSigner (& h , claimSet , signer )
147
+ }
130
148
if err != nil {
131
149
return nil , err
132
150
}
0 commit comments