@@ -19,19 +19,54 @@ const (
19
19
issuerGoogleAccountsNoScheme = "accounts.google.com"
20
20
)
21
21
22
- // keySet is an interface that lets us stub out verification policies for
23
- // testing. Outside of testing, it's always backed by a remoteKeySet.
24
- type keySet interface {
25
- verify (ctx context.Context , jws * jose.JSONWebSignature ) ([]byte , error )
22
+ // KeySet is a set of publc JSON Web Keys that can be used to validate the signature
23
+ // of JSON web tokens. This is expected to be backed by a remote key set through
24
+ // provider metadata discovery or an in-memory set of keys delivered out-of-band.
25
+ type KeySet interface {
26
+ // VerifySignature parses the JSON web token, verifies the signature, and returns
27
+ // the raw payload. Header and claim fields are validated by other parts of the
28
+ // package. For example, the KeySet does not need to check values such as signature
29
+ // algorithm, issuer, and audience since the IDTokenVerifier validates these values
30
+ // independently.
31
+ //
32
+ // If VerifySignature makes HTTP requests to verify the token, it's expected to
33
+ // use any HTTP client associated with the context through ClientContext.
34
+ VerifySignature (ctx context.Context , jwt string ) (payload []byte , err error )
26
35
}
27
36
28
37
// IDTokenVerifier provides verification for ID Tokens.
29
38
type IDTokenVerifier struct {
30
- keySet keySet
39
+ keySet KeySet
31
40
config * Config
32
41
issuer string
33
42
}
34
43
44
+ // NewVerifier returns a verifier manually constructed from a key set and issuer URL.
45
+ //
46
+ // It's easier to use provider discovery to construct an IDTokenVerifier than creating
47
+ // one directly. This method is intended to be used with provider that don't support
48
+ // metadata discovery, or avoiding round trips when the key set URL is already known.
49
+ //
50
+ // This constructor can be used to create a verifier directly using the issuer URL and
51
+ // JSON Web Key Set URL without using discovery:
52
+ //
53
+ // keySet := oidc.NewRemoteKeySet(ctx, "https://www.googleapis.com/oauth2/v3/certs")
54
+ // verifier := oidc.NewVerifier("https://accounts.google.com", keySet, config)
55
+ //
56
+ // Since KeySet is an interface, this constructor can also be used to supply custom
57
+ // public key sources. For example, if a user wanted to supply public keys out-of-band
58
+ // and hold them statically in-memory:
59
+ //
60
+ // // Custom KeySet implementation.
61
+ // keySet := newStatisKeySet(publicKeys...)
62
+ //
63
+ // // Verifier uses the custom KeySet implementation.
64
+ // verifier := oidc.NewVerifier("https://auth.example.com", keySet, config)
65
+ //
66
+ func NewVerifier (issuerURL string , keySet KeySet , config * Config ) * IDTokenVerifier {
67
+ return & IDTokenVerifier {keySet : keySet , config : config , issuer : issuerURL }
68
+ }
69
+
35
70
// Config is the configuration for an IDTokenVerifier.
36
71
type Config struct {
37
72
// Expected audience of the token. For a majority of the cases this is expected to be
@@ -63,7 +98,7 @@ func (p *Provider) Verifier(config *Config) *IDTokenVerifier {
63
98
return newVerifier (p .remoteKeySet , config , p .issuer )
64
99
}
65
100
66
- func newVerifier (keySet keySet , config * Config , issuer string ) * IDTokenVerifier {
101
+ func newVerifier (keySet KeySet , config * Config , issuer string ) * IDTokenVerifier {
67
102
// If SupportedSigningAlgs is empty defaults to only support RS256.
68
103
if len (config .SupportedSigningAlgs ) == 0 {
69
104
config .SupportedSigningAlgs = []string {RS256 }
@@ -165,7 +200,7 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
165
200
return nil , fmt .Errorf ("oidc: expected audience %q got %q" , v .config .ClientID , t .Audience )
166
201
}
167
202
} else {
168
- return nil , fmt .Errorf ("oidc: Invalid configuration. ClientID must be provided or SkipClientIDCheck must be set. " )
203
+ return nil , fmt .Errorf ("oidc: invalid configuration, clientID must be provided or SkipClientIDCheck must be set" )
169
204
}
170
205
}
171
206
@@ -194,7 +229,7 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
194
229
return nil , fmt .Errorf ("oidc: id token signed with unsupported algorithm, expected %q got %q" , v .config .SupportedSigningAlgs , sig .Header .Algorithm )
195
230
}
196
231
197
- gotPayload , err := v .keySet .verify (ctx , jws )
232
+ gotPayload , err := v .keySet .VerifySignature (ctx , rawIDToken )
198
233
if err != nil {
199
234
return nil , fmt .Errorf ("failed to verify signature: %v" , err )
200
235
}
0 commit comments