Copyright 2014 The Go 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 jwt implements the OAuth 2.0 JSON Web Token flow, commonly known as "two-legged OAuth 2.0". See: https://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-12
package jwt

import (
	
	
	
	
	
	
	
	
	

	
	
	
)

var (
	defaultGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer"
	defaultHeader    = &jws.Header{Algorithm: "RS256", Typ: "JWT"}
)
Config is the configuration for using JWT to fetch tokens, commonly known as "two-legged OAuth 2.0".
Email is the OAuth client identifier used when communicating with the configured OAuth provider.
PrivateKey contains the contents of an RSA private key or the contents of a PEM file that contains a private key. The provided private key is used to sign JWT payloads. PEM containers with a passphrase are not supported. Use the following command to convert a PKCS 12 file into a PEM. $ openssl pkcs12 -in key.p12 -out key.pem -nodes
PrivateKeyID contains an optional hint indicating which key is being used.
Subject is the optional user to impersonate.
Scopes optionally specifies a list of requested permission scopes.
TokenURL is the endpoint required to complete the 2-legged JWT flow.
Expires optionally specifies how long the token is valid for.
Audience optionally specifies the intended audience of the request. If empty, the value of TokenURL is used as the intended audience.
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.
TokenSource returns a JWT TokenSource using the configuration in c and the HTTP client from the provided context.
Client returns an HTTP client wrapping the context's HTTP transport and adding Authorization headers with tokens obtained from c. The returned client and its Transport should not be modified.
func ( *Config) ( context.Context) *http.Client {
	return oauth2.NewClient(, .TokenSource())
}
jwtSource is a source that always does a signed JWT request for a token. It should typically be wrapped with a reuseTokenSource.
type jwtSource struct {
	ctx  context.Context
	conf *Config
}

func ( jwtSource) () (*oauth2.Token, error) {
	,  := internal.ParseKey(.conf.PrivateKey)
	if  != nil {
		return nil, 
	}
	 := oauth2.NewClient(.ctx, nil)
	 := &jws.ClaimSet{
		Iss:           .conf.Email,
		Scope:         strings.Join(.conf.Scopes, " "),
		Aud:           .conf.TokenURL,
		PrivateClaims: .conf.PrivateClaims,
	}
	if  := .conf.Subject;  != "" {
prn is the old name of sub. Keep setting it to be compatible with legacy OAuth 2.0 providers.
		.Prn = 
	}
	if  := .conf.Expires;  > 0 {
		.Exp = time.Now().Add().Unix()
	}
	if  := .conf.Audience;  != "" {
		.Aud = 
	}
	 := *defaultHeader
	.KeyID = .conf.PrivateKeyID
	,  := jws.Encode(&, , )
	if  != nil {
		return nil, 
	}
	 := url.Values{}
	.Set("grant_type", defaultGrantType)
	.Set("assertion", )
	,  := .PostForm(.conf.TokenURL, )
	if  != nil {
		return nil, fmt.Errorf("oauth2: cannot fetch token: %v", )
	}
	defer .Body.Close()
	,  := ioutil.ReadAll(io.LimitReader(.Body, 1<<20))
	if  != nil {
		return nil, fmt.Errorf("oauth2: cannot fetch token: %v", )
	}
	if  := .StatusCode;  < 200 ||  > 299 {
		return nil, &oauth2.RetrieveError{
			Response: ,
			Body:     ,
		}
tokenRes is the JSON response body.
	var  struct {
		 string `json:"access_token"`
		   string `json:"token_type"`
		     string `json:"id_token"`
		   int64  `json:"expires_in"` // relative seconds from now
	}
	if  := json.Unmarshal(, &);  != nil {
		return nil, fmt.Errorf("oauth2: cannot fetch token: %v", )
	}
	 := &oauth2.Token{
		AccessToken: .,
		TokenType:   .,
	}
	 := make(map[string]interface{})
	json.Unmarshal(, &) // no error checks for optional fields
	 = .WithExtra()

	if  := .;  > 0 {
		.Expiry = time.Now().Add(time.Duration() * time.Second)
	}
decode returned id token to get expiry
		,  := jws.Decode()
		if  != nil {
			return nil, fmt.Errorf("oauth2: error decoding JWT token: %v", )
		}
		.Expiry = time.Unix(.Exp, 0)
	}
	if .conf.UseIDToken {
		if . == "" {
			return nil, fmt.Errorf("oauth2: response doesn't have JWT token")
		}
		.AccessToken = .
	}
	return , nil