forked from Mirrors/oauth2
google: add support for JWT Access Tokens
This is a new form of authentication for Google services, where instead of passing a signed claim to obtain a token from the OAuth endpoint, you present the signed claim *as* the token to the API endpoint. Fixes #139. Fixes #140. Change-Id: Ibf0f168a0ec111660ac08b86121c943fb96e146c Reviewed-on: https://go-review.googlesource.com/10667 Reviewed-by: David Symonds <dsymonds@golang.org> Reviewed-by: Dave Day <djd@golang.org>
This commit is contained in:
parent
8914e5017c
commit
397fe76494
|
@ -0,0 +1,67 @@
|
||||||
|
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rsa"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
"golang.org/x/oauth2/internal"
|
||||||
|
"golang.org/x/oauth2/jws"
|
||||||
|
)
|
||||||
|
|
||||||
|
// JWTAccessTokenSourceFromJSON uses a Google Developers service account JSON
|
||||||
|
// key file to read the credentials that authorize and authenticate the
|
||||||
|
// requests, and returns a TokenSource that does not use any OAuth2 flow but
|
||||||
|
// instead creates a JWT and sends that as the access token.
|
||||||
|
// The audience is typically a URL that specifies the scope of the credentials.
|
||||||
|
func JWTAccessTokenSourceFromJSON(jsonKey []byte, audience string) (oauth2.TokenSource, error) {
|
||||||
|
cfg, err := JWTConfigFromJSON(jsonKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("google: could not parse JSON key: %v", err)
|
||||||
|
}
|
||||||
|
pk, err := internal.ParseKey(cfg.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("google: could not parse key: %v", err)
|
||||||
|
}
|
||||||
|
ts := &jwtAccessTokenSource{
|
||||||
|
email: cfg.Email,
|
||||||
|
audience: audience,
|
||||||
|
pk: pk,
|
||||||
|
}
|
||||||
|
tok, err := ts.Token()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return oauth2.ReuseTokenSource(tok, ts), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type jwtAccessTokenSource struct {
|
||||||
|
email, audience string
|
||||||
|
pk *rsa.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *jwtAccessTokenSource) Token() (*oauth2.Token, error) {
|
||||||
|
iat := time.Now()
|
||||||
|
exp := iat.Add(time.Hour)
|
||||||
|
cs := &jws.ClaimSet{
|
||||||
|
Iss: ts.email,
|
||||||
|
Sub: ts.email,
|
||||||
|
Aud: ts.audience,
|
||||||
|
Iat: iat.Unix(),
|
||||||
|
Exp: exp.Unix(),
|
||||||
|
}
|
||||||
|
hdr := &jws.Header{
|
||||||
|
Algorithm: "RS256",
|
||||||
|
Typ: "JWT",
|
||||||
|
}
|
||||||
|
msg, err := jws.Encode(hdr, cs, ts.pk)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("google: could not encode JWT: %v", err)
|
||||||
|
}
|
||||||
|
return &oauth2.Token{AccessToken: msg}, nil
|
||||||
|
}
|
|
@ -27,8 +27,8 @@ type ClaimSet struct {
|
||||||
Iss string `json:"iss"` // email address of the client_id of the application making the access token request
|
Iss string `json:"iss"` // email address of the client_id of the application making the access token request
|
||||||
Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests
|
Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests
|
||||||
Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional).
|
Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional).
|
||||||
Exp int64 `json:"exp"` // the expiration time of the assertion
|
Exp int64 `json:"exp"` // the expiration time of the assertion (seconds since Unix epoch)
|
||||||
Iat int64 `json:"iat"` // the time the assertion was issued.
|
Iat int64 `json:"iat"` // the time the assertion was issued (seconds since Unix epoch)
|
||||||
Typ string `json:"typ,omitempty"` // token type (Optional).
|
Typ string `json:"typ,omitempty"` // token type (Optional).
|
||||||
|
|
||||||
// Email for which the application is requesting delegated access (Optional).
|
// Email for which the application is requesting delegated access (Optional).
|
||||||
|
|
Loading…
Reference in New Issue