forked from Mirrors/oauth2
Don't assume private key to be available on a traditional file system.
This commit is contained in:
parent
ee77246177
commit
03a41b25d4
|
@ -53,10 +53,15 @@ func Example_config() {
|
||||||
func Example_jWTConfig() {
|
func Example_jWTConfig() {
|
||||||
conf, err := oauth2.NewJWTConfig(&oauth2.JWTOptions{
|
conf, err := oauth2.NewJWTConfig(&oauth2.JWTOptions{
|
||||||
Email: "xxx@developer.gserviceaccount.com",
|
Email: "xxx@developer.gserviceaccount.com",
|
||||||
// The path to the pem file. If you have a p12 file instead, you
|
// The contents of your RSA private key or your PEM file
|
||||||
|
// that contains a private key.
|
||||||
|
// If you have a p12 file instead, you
|
||||||
// can use `openssl` to export the private key into a pem file.
|
// can use `openssl` to export the private key into a pem file.
|
||||||
|
//
|
||||||
// $ openssl pkcs12 -in key.p12 -out key.pem -nodes
|
// $ openssl pkcs12 -in key.p12 -out key.pem -nodes
|
||||||
PEMFilename: "/path/to/pem/file.pem",
|
//
|
||||||
|
// It only supports PEM containers with no passphrase.
|
||||||
|
PrivateKey: []byte("PRIVATE KEY CONTENTS"),
|
||||||
Scopes: []string{"SCOPE1", "SCOPE2"},
|
Scopes: []string{"SCOPE1", "SCOPE2"},
|
||||||
},
|
},
|
||||||
"https://provider.com/o/oauth2/token")
|
"https://provider.com/o/oauth2/token")
|
||||||
|
|
|
@ -49,10 +49,15 @@ func Example_serviceAccounts() {
|
||||||
// Developer Console (https://console.developers.google.com).
|
// Developer Console (https://console.developers.google.com).
|
||||||
config, err := google.NewServiceAccountConfig(&oauth2.JWTOptions{
|
config, err := google.NewServiceAccountConfig(&oauth2.JWTOptions{
|
||||||
Email: "xxx@developer.gserviceaccount.com",
|
Email: "xxx@developer.gserviceaccount.com",
|
||||||
// PEMFilename. If you have a p12 file instead, you
|
// The contents of your RSA private key or your PEM file
|
||||||
// can use `openssl` to export the private key into a pem file.
|
// that contains a private key.
|
||||||
|
// If you have a p12 file instead, you
|
||||||
|
// can use `openssl` to export the private key into a PEM file.
|
||||||
|
//
|
||||||
// $ openssl pkcs12 -in key.p12 -out key.pem -nodes
|
// $ openssl pkcs12 -in key.p12 -out key.pem -nodes
|
||||||
PEMFilename: "/path/to/pem/file.pem",
|
//
|
||||||
|
// Supports only PEM containers without a passphrase.
|
||||||
|
PrivateKey: []byte("PRIVATE KEY CONTENTS"),
|
||||||
Scopes: []string{
|
Scopes: []string{
|
||||||
"https://www.googleapis.com/auth/bigquery",
|
"https://www.googleapis.com/auth/bigquery",
|
||||||
},
|
},
|
||||||
|
|
47
jwt.go
47
jwt.go
|
@ -10,7 +10,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -31,17 +30,15 @@ type JWTOptions struct {
|
||||||
// the configured OAuth provider.
|
// the configured OAuth provider.
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
|
|
||||||
// PrivateKey is an RSA private key to sign JWS payloads.
|
// PrivateKey contains the contents of an RSA private key or the
|
||||||
PrivateKey *rsa.PrivateKey `json:"-"`
|
// contents of a PEM file that contains a private key. The provided
|
||||||
|
// private key is used to sign JWT payloads.
|
||||||
// The path to a PEM container that includes your private key.
|
// PEM containers with a passphrase are not supported.
|
||||||
// If PrivateKey is set, this field is ignored.
|
// Use the following command to convert a PKCS 12 file into a PEM.
|
||||||
//
|
//
|
||||||
// If you have a p12 file instead, you
|
|
||||||
// can use `openssl` to export the private key into a PEM file.
|
|
||||||
// $ openssl pkcs12 -in key.p12 -out key.pem -nodes
|
// $ openssl pkcs12 -in key.p12 -out key.pem -nodes
|
||||||
// PEM file should contain your private key.
|
//
|
||||||
PEMFilename string `json:"pemfilename"`
|
PrivateKey []byte `json:"-"`
|
||||||
|
|
||||||
// Scopes identify the level of access being requested.
|
// Scopes identify the level of access being requested.
|
||||||
Scopes []string `json:"scopes"`
|
Scopes []string `json:"scopes"`
|
||||||
|
@ -54,14 +51,7 @@ func NewJWTConfig(opts *JWTOptions, aud string) (*JWTConfig, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if opts.PrivateKey != nil {
|
parsedKey, err := parseKey(opts.PrivateKey)
|
||||||
return &JWTConfig{opts: opts, aud: audURL, key: opts.PrivateKey}, nil
|
|
||||||
}
|
|
||||||
contents, err := ioutil.ReadFile(opts.PEMFilename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
parsedKey, err := parsePemKey(contents)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -155,25 +145,26 @@ func (c *JWTConfig) FetchToken(existing *Token) (token *Token, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// parsePemKey parses the pem file to extract the private key.
|
// parseKey converts the binary contents of a private key file
|
||||||
// It returns an error if private key is not provided or the
|
// to an *rsa.PrivateKey. It detects whether the private key is in a
|
||||||
// provided key is invalid.
|
// PEM container or not. If so, it extracts the the private key
|
||||||
func parsePemKey(key []byte) (*rsa.PrivateKey, error) {
|
// from PEM container before conversion. It only supports PEM
|
||||||
invalidPrivateKeyErr := errors.New("oauth2: private key is invalid")
|
// containers with no passphrase.
|
||||||
|
func parseKey(key []byte) (*rsa.PrivateKey, error) {
|
||||||
block, _ := pem.Decode(key)
|
block, _ := pem.Decode(key)
|
||||||
if block == nil {
|
if block != nil {
|
||||||
return nil, invalidPrivateKeyErr
|
key = block.Bytes
|
||||||
}
|
}
|
||||||
parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
parsedKey, err := x509.ParsePKCS8PrivateKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
parsedKey, err = x509.ParsePKCS1PrivateKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parsed, ok := parsedKey.(*rsa.PrivateKey)
|
parsed, ok := parsedKey.(*rsa.PrivateKey)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, invalidPrivateKeyErr
|
return nil, errors.New("oauth2: private key is invalid")
|
||||||
}
|
}
|
||||||
return parsed, nil
|
return parsed, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue