jwt: support PrivateClaims in Config

This would help add extra claim for certain 2-leg JWT exchange.

For example, Google service account key can be used to generate an OIDC token, but Google TokenURL requires "target_audience" claims set.

See this example usage:
https://gist.github.com/wlhee/64bc518190053e2122ca1909c2977c67#file-exmaple-go-L29

Change-Id: Ic10b006e45a34210634c5a76261a7e3706066965
GitHub-Last-Rev: 7a6e247e68f742129ac9a5d5a5f1a8ad428ccb09
GitHub-Pull-Request: golang/oauth2#374
Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/166220
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Wenlei (Frank) He
2019-05-17 17:56:57 +00:00
committed by Brad Fitzpatrick
parent 9f3314589c
commit 950ef44c6e
2 changed files with 41 additions and 3 deletions

View File

@@ -66,6 +66,14 @@ type Config struct {
// request. If empty, the value of TokenURL is used as the
// intended audience.
Audience string
// PrivateClaims optionally specifies custom private claims in the JWT.
// See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
PrivateClaims map[string]interface{}
// UseIDToken optionally specifies whether ID token should be used instead
// of access token when the server returns both.
UseIDToken bool
}
// TokenSource returns a JWT TokenSource using the configuration
@@ -97,9 +105,10 @@ func (js jwtSource) Token() (*oauth2.Token, error) {
}
hc := oauth2.NewClient(js.ctx, nil)
claimSet := &jws.ClaimSet{
Iss: js.conf.Email,
Scope: strings.Join(js.conf.Scopes, " "),
Aud: js.conf.TokenURL,
Iss: js.conf.Email,
Scope: strings.Join(js.conf.Scopes, " "),
Aud: js.conf.TokenURL,
PrivateClaims: js.conf.PrivateClaims,
}
if subject := js.conf.Subject; subject != "" {
claimSet.Sub = subject
@@ -166,5 +175,11 @@ func (js jwtSource) Token() (*oauth2.Token, error) {
}
token.Expiry = time.Unix(claimSet.Exp, 0)
}
if js.conf.UseIDToken {
if tokenRes.IDToken == "" {
return nil, fmt.Errorf("oauth2: response doesn't have JWT token")
}
token.AccessToken = tokenRes.IDToken
}
return token, nil
}