jwt

package
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 30, 2014 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

The jwt package provides support for creating credentials for OAuth2 service account requests.

For examples of the package usage please see jwt_test.go. Example usage (error handling omitted for brevity):

// Craft the ClaimSet and JWT token.
iss := "XXXXXXXXXXXX@developer.gserviceaccount.com"
scope := "https://www.googleapis.com/auth/devstorage.read_only"
t := jwt.NewToken(iss, scope, pemKeyBytes)

// We need to provide a client.
c := &http.Client{}

// Get the access token.
o, _ := t.Assert(c)

// Form the request to the service.
req, _ := http.NewRequest("GET", "https://storage.googleapis.com/", nil)
req.Header.Set("Authorization", "OAuth "+o.AccessToken)
req.Header.Set("x-goog-api-version", "2")
req.Header.Set("x-goog-project-id", "XXXXXXXXXXXX")

// Make the request.
result, _ := c.Do(req)

For info on OAuth2 service accounts please see the online documentation. https://developers.google.com/accounts/docs/OAuth2ServiceAccount

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidKey = errors.New("Invalid Key")
)

Functions

This section is empty.

Types

type ClaimSet

type ClaimSet struct {
	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
	Aud   string `json:"aud"`             // descriptor of the intended target of the assertion (Optional).
	Prn   string `json:"prn,omitempty"`   // email for which the application is requesting delegated access (Optional).
	Exp   int64  `json:"exp"`
	Iat   int64  `json:"iat"`
	Typ   string `json:"typ,omitempty"`
	Sub   string `json:"sub,omitempty"` // Add support for googleapi delegation support

	// See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
	// This array is marshalled using custom code (see (c *ClaimSet) encode()).
	PrivateClaims map[string]interface{} `json:"-"`
	// contains filtered or unexported fields
}

The JWT claim set contains information about the JWT including the permissions being requested (scopes), the target of the token, the issuer, the time the token was issued, and the lifetime of the token.

Aud is usually https://accounts.google.com/o/oauth2/token

type Header struct {
	Algorithm string `json:"alg"`
	Type      string `json:"typ"`
	KeyId     string `json:"kid,omitempty"`
}

Header describes the algorithm and type of token being generated, and optionally a KeyID describing additional parameters for the signature.

type Signer

type Signer interface {
	Sign(in *Token) (tokenData, signature []byte, err error)
}

Signer is an interface that given a JWT token, returns the header & claim (serialized and urlEncoded to a byte slice), along with the signature and an error (if any occured). It could modify any data to sign (typically the KeyID).

Example usage where a SHA256 hash of the original url-encoded token with an added KeyID and secret data is used as a signature:

var privateData = "secret data added to hash, indexed by KeyID"

type SigningService struct{}

func (ss *SigningService) Sign(in *jwt.Token) (newTokenData, sig []byte, err error) {
	in.Header.KeyID = "signing service"
	newTokenData = in.EncodeWithoutSignature()
	dataToSign := fmt.Sprintf("%s.%s", newTokenData, privateData)
	h := sha256.New()
	_, err := h.Write([]byte(dataToSign))
	sig = h.Sum(nil)
	return
}

type Token

type Token struct {
	ClaimSet *ClaimSet // claim set used to construct the JWT
	Header   *Header   // header used to construct the JWT
	Key      []byte    // PEM printable encoding of the private key
	// contains filtered or unexported fields
}

A JWT is composed of three parts: a header, a claim set, and a signature. The well formed and encoded JWT can then be exchanged for an access token.

The Token is not a JWT, but is is encoded to produce a well formed JWT.

When obtaining a key from the Google API console it will be downloaded in a PKCS12 encoding. To use this key you will need to convert it to a PEM file. This can be achieved with openssl.

$ openssl pkcs12 -in <key.p12> -nocerts -passin pass:notasecret -nodes -out <key.pem>

The contents of this file can then be used as the Key.

func NewSignerToken

func NewSignerToken(iss, scope string, signer Signer) *Token

NewSignerToken returns a *Token, using an external signer function

func NewToken

func NewToken(iss, scope string, key []byte) *Token

NewToken returns a filled in *Token based on the standard header, and sets the Iat and Exp times based on when the call to Assert is made.

func (*Token) Assert

func (t *Token) Assert(c *http.Client) (*oauth.Token, error)

Assert obtains an *oauth.Token from the remote server by encoding and sending a JWT. The access_token will expire in one hour (3600 seconds) and cannot be refreshed (no refresh_token is returned with the response). Once this token expires call this method again to get a fresh one.

func (*Token) Encode

func (t *Token) Encode() (string, error)

Encode constructs and signs a Token returning a JWT ready to use for requesting an access token.

func (*Token) EncodeWithoutSignature

func (t *Token) EncodeWithoutSignature() string

EncodeWithoutSignature returns the url-encoded value of the Token before signing has occured (typically for use by external signers).

func (*Token) Expired

func (t *Token) Expired() bool

Expired returns a boolean value letting us know if the token has expired.

type Transport

type Transport struct {
	JWTToken   *Token
	OAuthToken *oauth.Token

	// Transport is the HTTP transport to use when making requests.
	// It will default to http.DefaultTransport if nil.
	Transport http.RoundTripper
}

Transport implements http.RoundTripper. When configured with a valid JWT and OAuth tokens it can be used to make authenticated HTTP requests.

t := &jwt.Transport{jwtToken, oauthToken}
r, _, err := t.Client().Get("http://example.org/url/requiring/auth")

It will automatically refresh the OAuth token if it can, updating in place.

func NewTransport

func NewTransport(token *Token) (*Transport, error)

Creates a new authenticated transport.

func (*Transport) Client

func (t *Transport) Client() *http.Client

Client returns an *http.Client that makes OAuth-authenticated requests.

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip executes a single HTTP transaction using the Transport's OAuthToken as authorization headers.

This method will attempt to renew the token if it has expired and may return an error related to that token renewal before attempting the client request. If the token cannot be renewed a non-nil os.Error value will be returned. If the token is invalid callers should expect HTTP-level errors, as indicated by the Response's StatusCode.

Directories

Path Synopsis
This program makes a read only call to the Google Cloud Storage API, authenticated with OAuth2.
This program makes a read only call to the Google Cloud Storage API, authenticated with OAuth2.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL