Repository: snowflakedb/gosnowflake
Pull request #353 (2020-11-30 23:07:17)

SNOW-224723 Update JWT Vendor
### Description
Updated JWT vendor from dgrijalva/jwt-go to form3tech-oss/jwt-go, a more actively developed and maintained version of the same fork, as per the recommendation of @sfc-gh-jelsesiy.

### Checklist
- [x] Code compiles correctly
- [x] Run ``make fmt`` to fix inconsistent formats
- [x] Run ``make lint`` to get lint errors and fix all of them
- [ ] Created tests which fail without the change (if possible)
- [x] All tests passing
- [ ] Extended the README / documentation, if necessary



Patch:
diff --git a/auth.go b/auth.go
index 1ebfda6..68c7a49 100644
--- a/auth.go
+++ b/auth.go
@@ -14,7 +14,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/dgrijalva/jwt-go/v4"
+	"github.com/form3tech-oss/jwt-go"
 	"github.com/google/uuid"
 
 	"crypto/sha256"
diff --git a/go.mod b/go.mod
index 0d0f046..a39d992 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.15
 
 require (
 	github.com/apache/arrow/go/arrow v0.0.0-20200601151325-b2287a20f230
-	github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1
+	github.com/form3tech-oss/jwt-go v3.2.2+incompatible
 	github.com/google/uuid v1.1.1
 	github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
 	github.com/snowflakedb/glog v0.0.0-20180824191149-f5055e6f21ce
diff --git a/go.sum b/go.sum
index 9cd6469..d4c72a5 100644
--- a/go.sum
+++ b/go.sum
@@ -2,8 +2,8 @@ github.com/apache/arrow/go/arrow v0.0.0-20200601151325-b2287a20f230 h1:5ultmol0y
 github.com/apache/arrow/go/arrow v0.0.0-20200601151325-b2287a20f230/go.mod h1:QNYViu/X0HXDHw7m3KXzWSVXIbfUvJqBFe6Gj8/pYA0=
 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU=
-github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=
+github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
+github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
 github.com/google/flatbuffers v1.11.0 h1:O7CEyB8Cb3/DmtxODGtLHcEvpr81Jm5qLg/hsHnxA2A=
 github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
 github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/.travis.yml b/vendor/github.com/dgrijalva/jwt-go/v4/.travis.yml
deleted file mode 100644
index ade3c58..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/.travis.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-language: go
-
-script:
-  - go vet ./...
-  - go test -v ./...
-
-go:
-  - "1.11"
-  - "1.12"
-  - "1.13"
-  - tip
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/claim_strings.go b/vendor/github.com/dgrijalva/jwt-go/v4/claim_strings.go
deleted file mode 100644
index 057b684..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/claim_strings.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package jwt
-
-import (
-	"encoding/json"
-	"reflect"
-)
-
-// ClaimStrings is used for parsing claim properties that
-// can be either a string or array of strings
-type ClaimStrings []string
-
-// ParseClaimStrings is used to produce a ClaimStrings value
-// from the various forms it may present during encoding/decodeing
-func ParseClaimStrings(value interface{}) (ClaimStrings, error) {
-	switch v := value.(type) {
-	case string:
-		return ClaimStrings{v}, nil
-	case []string:
-		return ClaimStrings(v), nil
-	case []interface{}:
-		result := make(ClaimStrings, 0, len(v))
-		for i, vv := range v {
-			if x, ok := vv.(string); ok {
-				result = append(result, x)
-			} else {
-				return nil, &json.UnsupportedTypeError{Type: reflect.TypeOf(v[i])}
-			}
-		}
-		return result, nil
-	case nil:
-		return nil, nil
-	default:
-		return nil, &json.UnsupportedTypeError{Type: reflect.TypeOf(v)}
-	}
-}
-
-// UnmarshalJSON implements the json package's Unmarshaler interface
-func (c *ClaimStrings) UnmarshalJSON(data []byte) error {
-	var value interface{}
-	err := json.Unmarshal(data, &value)
-	if err != nil {
-		return err
-	}
-
-	*c, err = ParseClaimStrings(value)
-	return err
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/claims.go b/vendor/github.com/dgrijalva/jwt-go/v4/claims.go
deleted file mode 100644
index a065328..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/claims.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package jwt
-
-// Claims is the interface used to hold the claims values of a token
-// For a type to be a Claims object, it must have a Valid method that determines
-// if the token is invalid for any supported reason
-// Claims are parsed and encoded using the standard library's encoding/json
-// package. Claims are passed directly to that.
-type Claims interface {
-	// A nil validation helper should use the default helper
-	Valid(*ValidationHelper) error
-}
-
-// StandardClaims is a structured version of Claims Section, as referenced at
-// https://tools.ietf.org/html/rfc7519#section-4.1
-// See examples for how to use this with your own claim types
-type StandardClaims struct {
-	Audience  ClaimStrings `json:"aud,omitempty"`
-	ExpiresAt *Time        `json:"exp,omitempty"`
-	ID        string       `json:"jti,omitempty"`
-	IssuedAt  *Time        `json:"iat,omitempty"`
-	Issuer    string       `json:"iss,omitempty"`
-	NotBefore *Time        `json:"nbf,omitempty"`
-	Subject   string       `json:"sub,omitempty"`
-}
-
-// Valid validates standard claims using ValidationHelper
-// Validates time based claims "exp, nbf" (see: WithLeeway)
-// Validates "aud" if present in claims. (see: WithAudience, WithoutAudienceValidation)
-// Validates "iss" if option is provided (see: WithIssuer)
-func (c StandardClaims) Valid(h *ValidationHelper) error {
-	var vErr error
-
-	if h == nil {
-		h = DefaultValidationHelper
-	}
-
-	if err := h.ValidateExpiresAt(c.ExpiresAt); err != nil {
-		vErr = wrapError(err, vErr)
-	}
-
-	if err := h.ValidateNotBefore(c.NotBefore); err != nil {
-		vErr = wrapError(err, vErr)
-	}
-
-	if err := h.ValidateAudience(c.Audience); err != nil {
-		vErr = wrapError(err, vErr)
-	}
-
-	if err := h.ValidateIssuer(c.Issuer); err != nil {
-		vErr = wrapError(err, vErr)
-	}
-
-	return vErr
-}
-
-// VerifyAudience compares the aud claim against cmp.
-func (c *StandardClaims) VerifyAudience(h *ValidationHelper, cmp string) error {
-	return h.ValidateAudienceAgainst(c.Audience, cmp)
-}
-
-// VerifyIssuer compares the iss claim against cmp.
-func (c *StandardClaims) VerifyIssuer(h *ValidationHelper, cmp string) error {
-	return h.ValidateIssuerAgainst(c.Issuer, cmp)
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/ecdsa.go b/vendor/github.com/dgrijalva/jwt-go/v4/ecdsa.go
deleted file mode 100644
index 9a0d608..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/ecdsa.go
+++ /dev/null
@@ -1,173 +0,0 @@
-package jwt
-
-import (
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/rand"
-	"encoding/asn1"
-	"fmt"
-	"math/big"
-)
-
-// SigningMethodECDSA implements the ECDSA family of signing methods signing methods
-// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification
-type SigningMethodECDSA struct {
-	Name      string
-	Hash      crypto.Hash
-	KeySize   int
-	CurveBits int
-}
-
-// Mirrors the struct from crypto/ecdsa, we expect ecdsa.PrivateKey.Sign function to return this struct asn1 encoded
-type ecdsaSignature struct {
-	R, S *big.Int
-}
-
-// Specific instances for EC256 and company
-var (
-	SigningMethodES256 *SigningMethodECDSA
-	SigningMethodES384 *SigningMethodECDSA
-	SigningMethodES512 *SigningMethodECDSA
-)
-
-func init() {
-	// ES256
-	SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256}
-	RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod {
-		return SigningMethodES256
-	})
-
-	// ES384
-	SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384}
-	RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod {
-		return SigningMethodES384
-	})
-
-	// ES512
-	SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521}
-	RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod {
-		return SigningMethodES512
-	})
-}
-
-// Alg implements SigningMethod
-func (m *SigningMethodECDSA) Alg() string {
-	return m.Name
-}
-
-// Verify implements the Verify method from SigningMethod
-// For this verify method, key must be an ecdsa.PublicKey struct
-func (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error {
-	var err error
-
-	// Decode the signature
-	var sig []byte
-	if sig, err = DecodeSegment(signature); err != nil {
-		return err
-	}
-
-	// Get the key
-	var ecdsaKey *ecdsa.PublicKey
-	var ok bool
-
-	switch k := key.(type) {
-	case *ecdsa.PublicKey:
-		ecdsaKey = k
-	case crypto.Signer:
-		pub := k.Public()
-		if ecdsaKey, ok = pub.(*ecdsa.PublicKey); !ok {
-			return &InvalidKeyError{Message: fmt.Sprintf("crypto.Signer returned an unexpected public key type: %T", pub)}
-		}
-	default:
-		return NewInvalidKeyTypeError("*ecdsa.PublicKey or crypto.Signer", key)
-	}
-
-	if len(sig) != 2*m.KeySize {
-		return &UnverfiableTokenError{Message: "signature length is invalid"}
-	}
-
-	r := big.NewInt(0).SetBytes(sig[:m.KeySize])
-	s := big.NewInt(0).SetBytes(sig[m.KeySize:])
-
-	// Create hasher
-	if !m.Hash.Available() {
-		return ErrHashUnavailable
-	}
-	hasher := m.Hash.New()
-	hasher.Write([]byte(signingString))
-
-	// Verify the signature
-	if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus == true {
-		return nil
-	}
-	return new(InvalidSignatureError)
-}
-
-// Sign implements the Sign method from SigningMethod
-// For this signing method, key must be an ecdsa.PrivateKey struct
-func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) {
-	var signer crypto.Signer
-	var pub *ecdsa.PublicKey
-	var ok bool
-
-	if signer, ok = key.(crypto.Signer); !ok {
-		return "", NewInvalidKeyTypeError("*ecdsa.PrivateKey or crypto.Signer", key)
-	}
-
-	//sanity check that the signer is an ecdsa signer
-	if pub, ok = signer.Public().(*ecdsa.PublicKey); !ok {
-		return "", &InvalidKeyError{Message: fmt.Sprintf("signer returned unexpected public key type: %T", pub)}
-	}
-
-	// Create the hasher
-	if !m.Hash.Available() {
-		return "", ErrHashUnavailable
-	}
-
-	hasher := m.Hash.New()
-	hasher.Write([]byte(signingString))
-
-	// Sign the string and return r, s
-	asn1Sig, err := signer.Sign(rand.Reader, hasher.Sum(nil), m.Hash)
-	if err != nil {
-		return "", err
-	}
-
-	//the ecdsa.PrivateKey Sign function returns an asn1 encoded signature which is not what we want
-	// so we unmarshal it to get r and s to encode as described in rfc7518 section-3.4
-	var ecdsaSig ecdsaSignature
-	rest, err := asn1.Unmarshal(asn1Sig, &ecdsaSig)
-	if err != nil {
-		return "", err
-	}
-
-	if len(rest) != 0 {
-		return "", &UnverfiableTokenError{Message: "unexpected extra bytes in ecda signature"}
-	}
-
-	curveBits := pub.Curve.Params().BitSize
-
-	if m.CurveBits != curveBits {
-		return "", &InvalidKeyError{Message: "CurveBits in public key don't match those in signing method"}
-	}
-
-	keyBytes := curveBits / 8
-	if curveBits%8 > 0 {
-		keyBytes++
-	}
-
-	// We serialize the output (r and s) into big-endian byte arrays and pad
-	// them with zeros on the left to make sure the sizes work out. Both arrays
-	// must be keyBytes long, and the output must be 2*keyBytes long.
-	rBytes := ecdsaSig.R.Bytes()
-	rBytesPadded := make([]byte, keyBytes)
-	copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
-
-	sBytes := ecdsaSig.S.Bytes()
-	sBytesPadded := make([]byte, keyBytes)
-	copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
-
-	out := append(rBytesPadded, sBytesPadded...)
-
-	return EncodeSegment(out), nil
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/errors.go b/vendor/github.com/dgrijalva/jwt-go/v4/errors.go
deleted file mode 100644
index d7a53ba..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/errors.go
+++ /dev/null
@@ -1,204 +0,0 @@
-package jwt
-
-import (
-	"fmt"
-	"time"
-)
-
-// Error constants
-var (
-	ErrHashUnavailable = new(HashUnavailableError)
-)
-
-// Embeds b within a, if a is a valid wrapper. returns a
-// If a is not a valid wrapper, b is dropped
-// If one of the errors is nil, the other is returned
-func wrapError(a, b error) error {
-	if b == nil {
-		return a
-	}
-	if a == nil {
-		return b
-	}
-
-	type iErrorWrapper interface {
-		Wrap(error)
-	}
-	if w, ok := a.(iErrorWrapper); ok {
-		w.Wrap(b)
-	}
-	return a
-}
-
-// ErrorWrapper provides a simple, concrete helper for implementing nestable errors
-type ErrorWrapper struct{ err error }
-
-// Unwrap implements xerrors.Wrapper
-func (w ErrorWrapper) Unwrap() error {
-	return w.err
-}
-
-// Wrap stores the provided error value and returns it when Unwrap is called
-func (w ErrorWrapper) Wrap(err error) {
-	w.err = err
-}
-
-// InvalidKeyError is returned if the key is unusable for some reason other than type
-type InvalidKeyError struct {
-	Message string
-	ErrorWrapper
-}
-
-func (e *InvalidKeyError) Error() string {
-	return fmt.Sprintf("key is invalid: %v", e.Message)
-}
-
-// InvalidKeyTypeError is returned if the key is unusable because it is of an incompatible type
-type InvalidKeyTypeError struct {
-	Expected, Received string // String descriptions of expected and received types
-	ErrorWrapper
-}
-
-func (e *InvalidKeyTypeError) Error() string {
-	if e.Expected == "" && e.Received == "" {
-		return "key is of invalid type"
-	}
-	return fmt.Sprintf("key is of invalid type: expected %v, received %v", e.Expected, e.Received)
-}
-
-// NewInvalidKeyTypeError creates an InvalidKeyTypeError, automatically capturing the type
-// of received
-func NewInvalidKeyTypeError(expected string, received interface{}) error {
-	return &InvalidKeyTypeError{Expected: expected, Received: fmt.Sprintf("%T", received)}
-}
-
-// MalformedTokenError means the token failed to parse or exhibits some other
-// non-standard property that prevents it being processed by this library
-type MalformedTokenError struct {
-	Message string
-	ErrorWrapper
-}
-
-func (e *MalformedTokenError) Error() string {
-	if e.Message == "" {
-		return "token is malformed"
-	}
-	return fmt.Sprintf("token is malformed: %v", e.Message)
-}
-
-// UnverfiableTokenError means there's something wrong with the signature that prevents
-// this library from verifying it.
-type UnverfiableTokenError struct {
-	Message string
-	ErrorWrapper
-}
-
-func (e *UnverfiableTokenError) Error() string {
-	if e.Message == "" {
-		return "token is unverifiable"
-	}
-	return fmt.Sprintf("token is unverifiable: %v", e.Message)
-}
-
-// InvalidSignatureError means the signature on the token is invalid
-type InvalidSignatureError struct {
-	Message string
-	ErrorWrapper
-}
-
-func (e *InvalidSignatureError) Error() string {
-	if e.Message == "" {
-		return "token signature is invalid"
-	}
-	return fmt.Sprintf("token signature is invalid: %v", e.Message)
-}
-
-// TokenExpiredError allows the caller to know the delta between now and the expired time and the unvalidated claims.
-// A client system may have a bug that doesn't refresh a token in time, or there may be clock skew so this information can help you understand.
-type TokenExpiredError struct {
-	At           time.Time     // The time at which the exp was evaluated. Includes leeway.
-	ExpiredBy    time.Duration // How long the token had been expired at time of evaluation
-	ErrorWrapper               // Value for unwrapping
-}
-
-func (e *TokenExpiredError) Error() string {
-	return fmt.Sprintf("token is expired by %v", e.ExpiredBy)
-}
-
-// TokenNotValidYetError means the token failed the 'nbf' check. It's possible
-// this token will become valid once the 'nbf' time is reached. If you are encountering
-// this unexpectedly, you may want to provide a bit of Leeway to account for clock skew. See WithLeeway
-type TokenNotValidYetError struct {
-	At           time.Time     // The time at which the exp was evaluated. Includes leeway.
-	EarlyBy      time.Duration // How long the token had been expired at time of evaluation
-	ErrorWrapper               // Value for unwrapping
-}
-
-func (e *TokenNotValidYetError) Error() string {
-	return fmt.Sprintf("token is not valid yet; wait %v", e.EarlyBy)
-}
-
-// InvalidAudienceError means the token failed the audience check
-// per the spec, if an 'aud' claim is present, the value must be verified
-// See: WithAudience and WithoutAudienceValidation
-type InvalidAudienceError struct {
-	Message string
-	ErrorWrapper
-}
-
-func (e *InvalidAudienceError) Error() string {
-	if e.Message == "" {
-		return "token audience is invalid"
-	}
-	return fmt.Sprintf("token audience is invalid: %v", e.Message)
-}
-
-// InvalidIssuerError means the token failed issuer validation
-// Issuer validation is only run, by default, if the WithIssuer option is provided
-type InvalidIssuerError struct {
-	Message string
-	ErrorWrapper
-}
-
-func (e *InvalidIssuerError) Error() string {
-	if e.Message == "" {
-		return "token issuer is invalid"
-	}
-	return fmt.Sprintf("token issuer is invalid: %v", e.Message)
-}
-
-// InvalidClaimsError is a catchall type for claims errors that don't have their own type
-type InvalidClaimsError struct {
-	Message string
-	ErrorWrapper
-}
-
-func (e *InvalidClaimsError) Error() string {
-	if e.Message == "" {
-		return "token claim is invalid"
-	}
-	return fmt.Sprintf("token claim is invalid: %v", e.Message)
-}
-
-// SigningError is a catchall type for signing errors
-type SigningError struct {
-	Message string
-	ErrorWrapper
-}
-
-func (e *SigningError) Error() string {
-	if e.Message == "" {
-		return "error encountered during signing"
-	}
-	return fmt.Sprintf("error encountered during signing: %v", e.Message)
-}
-
-// HashUnavailableError measn the request hash function isn't available
-// See: https://godoc.org/crypto#Hash.Available
-type HashUnavailableError struct {
-	ErrorWrapper
-}
-
-func (e *HashUnavailableError) Error() string {
-	return "the requested hash function is unavailable"
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/go.mod b/vendor/github.com/dgrijalva/jwt-go/v4/go.mod
deleted file mode 100644
index 284213d..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/go.mod
+++ /dev/null
@@ -1,5 +0,0 @@
-module github.com/dgrijalva/jwt-go/v4
-
-go 1.12
-
-require golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/go.sum b/vendor/github.com/dgrijalva/jwt-go/v4/go.sum
deleted file mode 100644
index 3ab73ea..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/go.sum
+++ /dev/null
@@ -1,2 +0,0 @@
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/keyfunc.go b/vendor/github.com/dgrijalva/jwt-go/v4/keyfunc.go
deleted file mode 100644
index 2f15a8f..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/keyfunc.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package jwt
-
-import "fmt"
-
-// Keyfunc is the type passed to Parse methods to supply
-// the key for verification.  The function receives the parsed,
-// but unverified Token.  This allows you to use properties in the
-// Header of the token (such as `kid`) to identify which key to use.
-type Keyfunc func(*Token) (interface{}, error)
-
-// KnownKeyfunc is a helper for generating a Keyfunc from a known
-// signing method and key. If your implementation only supports a single signing method
-// and key, this is for you.
-func KnownKeyfunc(signingMethod SigningMethod, key interface{}) Keyfunc {
-	return func(t *Token) (interface{}, error) {
-		if signingMethod.Alg() != t.Header["alg"] {
-			return nil, fmt.Errorf("unexpected signing method: %v, expected: %v", t.Header["alg"], signingMethod.Alg())
-		}
-		return key, nil
-	}
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/map_claims.go b/vendor/github.com/dgrijalva/jwt-go/v4/map_claims.go
deleted file mode 100644
index d721c33..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/map_claims.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package jwt
-
-// MapClaims is the Claims type that uses the map[string]interface{} for JSON decoding
-// This is the default Claims type if you don't supply one
-type MapClaims map[string]interface{}
-
-// VerifyAudience compares the aud claim against cmp.
-func (m MapClaims) VerifyAudience(h *ValidationHelper, cmp string) error {
-	if aud, err := ParseClaimStrings(m["aud"]); err == nil && aud != nil {
-		return h.ValidateAudienceAgainst(aud, cmp)
-	} else if err != nil {
-		return &MalformedTokenError{Message: "couldn't parse 'aud' value"}
-	}
-	return nil
-}
-
-// VerifyIssuer compares the iss claim against cmp.
-func (m MapClaims) VerifyIssuer(h *ValidationHelper, cmp string) error {
-	iss, ok := m["iss"].(string)
-	if !ok {
-		return &InvalidIssuerError{Message: "'iss' expected but not present"}
-	}
-	return h.ValidateIssuerAgainst(iss, cmp)
-}
-
-// Valid validates standard claims using ValidationHelper
-// Validates time based claims "exp, nbf" (see: WithLeeway)
-// Validates "aud" if present in claims. (see: WithAudience, WithoutAudienceValidation)
-// Validates "iss" if option is provided (see: WithIssuer)
-func (m MapClaims) Valid(h *ValidationHelper) error {
-	var vErr error
-
-	if h == nil {
-		h = DefaultValidationHelper
-	}
-
-	exp, err := m.LoadTimeValue("exp")
-	if err != nil {
-		return err
-	}
-
-	if err = h.ValidateExpiresAt(exp); err != nil {
-		vErr = wrapError(err, vErr)
-	}
-
-	nbf, err := m.LoadTimeValue("nbf")
-	if err != nil {
-		return err
-	}
-
-	if err = h.ValidateNotBefore(nbf); err != nil {
-		vErr = wrapError(err, vErr)
-	}
-
-	// Try to parse the 'aud' claim
-	if aud, err := ParseClaimStrings(m["aud"]); err == nil && aud != nil {
-		// If it's present and well formed, validate
-		if err = h.ValidateAudience(aud); err != nil {
-			vErr = wrapError(err, vErr)
-		}
-	} else if err != nil {
-		// If it's present and not well formed, return an error
-		return &MalformedTokenError{Message: "couldn't parse 'aud' value"}
-	}
-
-	iss, _ := m["iss"].(string)
-	if err = h.ValidateIssuer(iss); err != nil {
-		vErr = wrapError(err, vErr)
-	}
-
-	return vErr
-}
-
-// LoadTimeValue extracts a *Time value from a key in m
-func (m MapClaims) LoadTimeValue(key string) (*Time, error) {
-	value, ok := m[key]
-	if !ok {
-		// No value present in map
-		return nil, nil
-	}
-
-	return ParseTime(value)
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/parser.go b/vendor/github.com/dgrijalva/jwt-go/v4/parser.go
deleted file mode 100644
index 1f1a9c0..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/parser.go
+++ /dev/null
@@ -1,168 +0,0 @@
-package jwt
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"strings"
-)
-
-// Parser is the type used to parse and validate a JWT token from string
-type Parser struct {
-	validMethods         []string          // If populated, only these methods will be considered valid
-	useJSONNumber        bool              // Use JSON Number format in JSON decoder
-	skipClaimsValidation bool              // Skip claims validation during token parsing
-	unmarshaller         TokenUnmarshaller // Use this instead of encoding/json
-	*ValidationHelper
-}
-
-// NewParser returns a new Parser with the specified options
-func NewParser(options ...ParserOption) *Parser {
-	p := &Parser{
-		ValidationHelper: new(ValidationHelper),
-	}
-	for _, option := range options {
-		option(p)
-	}
-	return p
-}
-
-// Parse will parse, validate, and return a token.
-// keyFunc will receive the parsed token and should return the key for validating.
-// If everything is kosher, err will be nil
-func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
-	return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc)
-}
-
-// ParseWithClaims is just like parse, but with the claims type specified
-func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
-	token, parts, err := p.ParseUnverified(tokenString, claims)
-	if err != nil {
-		return token, err
-	}
-
-	// Verify signing method is in the required set
-	if p.validMethods != nil {
-		var signingMethodValid = false
-		var alg = token.Method.Alg()
-		for _, m := range p.validMethods {
-			if m == alg {
-				signingMethodValid = true
-				break
-			}
-		}
-		if !signingMethodValid {
-			// signing method is not in the listed set
-			return token, &UnverfiableTokenError{Message: fmt.Sprintf("signing method %v is invalid", alg)}
-		}
-	}
-
-	// Lookup key
-	var key interface{}
-	if keyFunc == nil {
-		// keyFunc was not provided.  short circuiting validation
-		return token, &UnverfiableTokenError{Message: "no Keyfunc was provided."}
-	}
-	if key, err = keyFunc(token); err != nil {
-		// keyFunc returned an error
-		return token, wrapError(&UnverfiableTokenError{Message: "Keyfunc returned an error"}, err)
-	}
-
-	var vErr error
-
-	// Perform validation
-	token.Signature = parts[2]
-	if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil {
-		vErr = wrapError(&InvalidSignatureError{}, err)
-	}
-
-	// Validate Claims
-	if !p.skipClaimsValidation && vErr == nil {
-		if err := token.Claims.Valid(p.ValidationHelper); err != nil {
-			vErr = wrapError(err, vErr)
-		}
-	}
-
-	if vErr == nil {
-		token.Valid = true
-	}
-
-	return token, vErr
-}
-
-// ParseUnverified is used to inspect a token without validating it
-// WARNING: Don't use this method unless you know what you're doing
-//
-// This method parses the token but doesn't validate the signature. It's only
-// ever useful in cases where you know the signature is valid (because it has
-// been checked previously in the stack) and you want to extract values from
-// it. Or for debuggery.
-func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) {
-	parts = strings.Split(tokenString, ".")
-	if len(parts) != 3 {
-		return nil, parts, &MalformedTokenError{Message: "token contains an invalid number of segments"}
-	}
-
-	token = &Token{Raw: tokenString}
-
-	// choose unmarshaller
-	var unmarshaller = p.unmarshaller
-	if unmarshaller == nil {
-		unmarshaller = p.defaultUnmarshaller
-	}
-
-	// parse Header
-	var headerBytes []byte
-	if headerBytes, err = DecodeSegment(parts[0]); err != nil {
-		if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") {
-			return token, parts, &MalformedTokenError{Message: "tokenstring should not contain 'bearer '"}
-		}
-		return token, parts, wrapError(&MalformedTokenError{Message: "failed to decode token header"}, err)
-	}
-	if err = unmarshaller(CodingContext{HeaderFieldDescriptor, nil}, headerBytes, &token.Header); err != nil {
-		return token, parts, wrapError(&MalformedTokenError{Message: "failed to unmarshal token header"}, err)
-	}
-
-	// parse Claims
-	var claimBytes []byte
-	token.Claims = claims
-
-	if claimBytes, err = DecodeSegment(parts[1]); err != nil {
-		return token, parts, wrapError(&MalformedTokenError{Message: "failed to decode token claims"}, err)
-	}
-	// JSON Decode.  Special case for map type to avoid weird pointer behavior
-	ctx := CodingContext{ClaimsFieldDescriptor, token.Header}
-	if c, ok := token.Claims.(MapClaims); ok {
-		err = unmarshaller(ctx, claimBytes, &c)
-	} else {
-		err = unmarshaller(ctx, claimBytes, &claims)
-	}
-	// Handle decode error
-	if err != nil {
-		return token, parts, wrapError(&MalformedTokenError{Message: "failed to unmarshal token claims"}, err)
-	}
-
-	// Lookup signature method
-	if method, ok := token.Header["alg"].(string); ok {
-		if token.Method = GetSigningMethod(method); token.Method == nil {
-			return token, parts, &UnverfiableTokenError{Message: "signing method (alg) is unavailable."}
-		}
-	} else {
-		return token, parts, &UnverfiableTokenError{Message: "signing method (alg) is unspecified."}
-	}
-
-	return token, parts, nil
-}
-
-func (p *Parser) defaultUnmarshaller(ctx CodingContext, data []byte, v interface{}) error {
-	// If we don't need a special parser, use Unmarshal
-	// We never use a special encoder for the header
-	if !p.useJSONNumber || ctx.FieldDescriptor == HeaderFieldDescriptor {
-		return json.Unmarshal(data, v)
-	}
-
-	// To enable the JSONNumber mode, we must use Decoder instead of Unmarshal
-	dec := json.NewDecoder(bytes.NewBuffer(data))
-	dec.UseNumber()
-	return dec.Decode(v)
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/parser_option.go b/vendor/github.com/dgrijalva/jwt-go/v4/parser_option.go
deleted file mode 100644
index fd285eb..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/parser_option.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package jwt
-
-import "time"
-
-// ParserOption implements functional options for parser behavior
-// see: https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis
-type ParserOption func(*Parser)
-
-// WithValidMethods returns the ParserOption for specifying valid signing methods
-func WithValidMethods(valid []string) ParserOption {
-	return func(p *Parser) {
-		p.validMethods = valid
-	}
-}
-
-// WithJSONNumber returns the ParserOption for using json.Number instead of float64 when parsing
-// numeric values. Used most commonly with MapClaims, but it can be useful in some cases with
-// structured claims types
-func WithJSONNumber() ParserOption {
-	return func(p *Parser) {
-		p.useJSONNumber = true
-	}
-}
-
-// WithoutClaimsValidation returns the ParserOption for disabling claims validation
-// This does not disable signature validation. Use this if you want intend to implement
-// claims validation via other means
-func WithoutClaimsValidation() ParserOption {
-	return func(p *Parser) {
-		p.skipClaimsValidation = true
-	}
-}
-
-// WithLeeway returns the ParserOption for specifying the leeway window.
-func WithLeeway(d time.Duration) ParserOption {
-	return func(p *Parser) {
-		p.ValidationHelper.leeway = d
-	}
-}
-
-// WithAudience returns the ParserOption for specifying an expected aud member value
-func WithAudience(aud string) ParserOption {
-	return func(p *Parser) {
-		p.ValidationHelper.audience = &aud
-	}
-}
-
-// WithoutAudienceValidation returns the ParserOption that specifies audience check should be skipped
-func WithoutAudienceValidation() ParserOption {
-	return func(p *Parser) {
-		p.ValidationHelper.skipAudience = true
-	}
-}
-
-// WithIssuer returns the ParserOption that specifies a value to compare against the iss claim
-func WithIssuer(iss string) ParserOption {
-	return func(p *Parser) {
-		p.ValidationHelper.issuer = &iss
-	}
-}
-
-// TokenUnmarshaller is the function signature required to supply custom JSON decoding logic.
-// It is the same as json.Marshal with the addition of the FieldDescriptor.
-// The field value will let your marshaller know which field is being processed.
-// This is to facilitate things like compression, where you wouldn't want to compress
-// the head.
-type TokenUnmarshaller func(ctx CodingContext, data []byte, v interface{}) error
-
-// WithUnmarshaller returns the ParserOption that replaces the specified decoder
-func WithUnmarshaller(um TokenUnmarshaller) ParserOption {
-	return func(p *Parser) {
-		p.unmarshaller = um
-	}
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/signing_option.go b/vendor/github.com/dgrijalva/jwt-go/v4/signing_option.go
deleted file mode 100644
index cecead2..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/signing_option.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package jwt
-
-// CodingContext provides context to TokenMarshaller and TokenUnmarshaller
-type CodingContext struct {
-	FieldDescriptor                        // Which field are we encoding/decoding?
-	Header          map[string]interface{} // The token Header, if available
-}
-
-// FieldDescriptor describes which field is being processed. Used by CodingContext
-// This is to enable the marshaller to treat the head and body differently
-type FieldDescriptor uint8
-
-// Constants describe which field is being processed by custom Marshaller
-const (
-	HeaderFieldDescriptor FieldDescriptor = 0
-	ClaimsFieldDescriptor FieldDescriptor = 1
-)
-
-// SigningOption can be passed to signing related methods on Token to customize behavior
-type SigningOption func(*signingOptions)
-
-type signingOptions struct {
-	marshaller TokenMarshaller
-}
-
-// TokenMarshaller is the interface you must implement to provide custom JSON marshalling
-// behavior. It is the same as json.Marshal with the addition of the FieldDescriptor.
-// The field value will let your marshaller know which field is being processed.
-// This is to facilitate things like compression, where you wouldn't want to compress
-// the head.
-type TokenMarshaller func(ctx CodingContext, v interface{}) ([]byte, error)
-
-// WithMarshaller returns a SigningOption that will tell the signing code to use your custom Marshaller
-func WithMarshaller(m TokenMarshaller) SigningOption {
-	return func(o *signingOptions) {
-		o.marshaller = m
-	}
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/time.go b/vendor/github.com/dgrijalva/jwt-go/v4/time.go
deleted file mode 100644
index aee72ae..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/time.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package jwt
-
-import (
-	"encoding/json"
-	"reflect"
-	"time"
-)
-
-// TimePrecision determines how precisely time is measured
-// by this library. When serializing and deserialzing tokens,
-// time values are automatically truncated to this precision.
-// See the time package's Truncate method for more detail
-const TimePrecision = time.Microsecond
-
-// Time is how this library represents time values. It's mostly
-// a wrapper for the standard library's time.Time, but adds
-// specialized JSON decoding behavior to interop with the way
-// time is represented by JWT. Also makes it possible to represent
-// nil values.
-type Time struct {
-	time.Time
-}
-
-// NewTime creates a new Time value from a float64, following
-// the JWT spec.
-func NewTime(t float64) *Time {
-	return At(time.Unix(0, int64(t*float64(time.Second))))
-}
-
-// Now returns a new Time value using the current time.
-// You can override Now by changing the value of TimeFunc
-func Now() *Time {
-	return At(TimeFunc())
-}
-
-// At makes a Time value from a standard library time.Time value
-func At(at time.Time) *Time {
-	return &Time{at.Truncate(TimePrecision)}
-}
-
-// ParseTime is used for creating a Time value from various
-// possible representations that can occur in serialization.
-func ParseTime(value interface{}) (*Time, error) {
-	switch v := value.(type) {
-	case int64:
-		return NewTime(float64(v)), nil
-	case float64:
-		return NewTime(v), nil
-	case json.Number:
-		vv, err := v.Float64()
-		if err != nil {
-			return nil, err
-		}
-		return NewTime(vv), nil
-	case nil:
-		return nil, nil
-	default:
-		return nil, &json.UnsupportedTypeError{Type: reflect.TypeOf(v)}
-	}
-}
-
-// UnmarshalJSON implements the json package's Unmarshaler interface
-func (t *Time) UnmarshalJSON(data []byte) error {
-	var value json.Number
-	err := json.Unmarshal(data, &value)
-	if err != nil {
-		return err
-	}
-	v, err := ParseTime(value)
-	*t = *v
-	return err
-}
-
-// MarshalJSON implements the json package's Marshaler interface
-func (t *Time) MarshalJSON() ([]byte, error) {
-	f := float64(t.Truncate(TimePrecision).UnixNano()) / float64(time.Second)
-	return json.Marshal(f)
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/validation_helper.go b/vendor/github.com/dgrijalva/jwt-go/v4/validation_helper.go
deleted file mode 100644
index 2edd0a4..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/v4/validation_helper.go
+++ /dev/null
@@ -1,151 +0,0 @@
-package jwt
-
-import (
-	"crypto/subtle"
-	"fmt"
-	"time"
-)
-
-// DefaultValidationHelper is used by Claims.Valid if none is provided
-var DefaultValidationHelper = &ValidationHelper{}
-
-// ValidationHelper is built by the parser and passed
-// to Claims.Value to carry parse/validation options
-// This standalone type exists to allow implementations to do whatever custom
-// behavior is required while still being able to call upon the standard behavior
-// as necessary.
-type ValidationHelper struct {
-	nowFunc      func() time.Time // Override for time.Now. Mostly used for testing
-	leeway       time.Duration    // Leeway to provide when validating time values
-	audience     *string          // Expected audience value
-	skipAudience bool             // Ignore aud check
-	issuer       *string          // Expected issuer value. ignored if nil
-}
-
-// NewValidationHelper creates a validation helper from a list of parser options
-// Not all parser options will impact validation
-// If you already have a custom parser, you can use its ValidationHelper value
-// instead of creating a new one
-func NewValidationHelper(options ...ParserOption) *ValidationHelper {
-	p := NewParser(options...)
-	return p.ValidationHelper
-}
-
-func (h *ValidationHelper) now() time.Time {
-	if h.nowFunc != nil {
-		return h.nowFunc()
-	}
-	return TimeFunc()
-}
-
-// Before returns true if Now is before t
-// Takes leeway into account
-func (h *ValidationHelper) Before(t time.Time) bool {
-	return h.now().Before(t.Add(-h.leeway))
-}
-
-// After returns true if Now is after t
-// Takes leeway into account
-func (h *ValidationHelper) After(t time.Time) bool {
-	return h.now().After(t.Add(h.leeway))
-}
-
-// ValidateExpiresAt returns an error if the expiration time is invalid
-// Takes leeway into account
-func (h *ValidationHelper) ValidateExpiresAt(exp *Time) error {
-	// 'exp' claim is not set. ignore.
-	if exp == nil {
-		return nil
-	}
-
-	// Expiration has passed
-	if h.After(exp.Time) {
-		delta := h.now().Sub(exp.Time)
-		return &TokenExpiredError{At: h.now(), ExpiredBy: delta}
-	}
-
-	// Expiration has not passed
-	return nil
-}
-
-// ValidateNotBefore returns an error if the nbf time has not been reached
-// Takes leeway into account
-func (h *ValidationHelper) ValidateNotBefore(nbf *Time) error {
-	// 'nbf' claim is not set. ignore.
-	if nbf == nil {
-		return nil
-	}
-
-	// Nbf hasn't been reached
-	if h.Before(nbf.Time) {
-		delta := nbf.Time.Sub(h.now())
-		return &TokenNotValidYetError{At: h.now(), EarlyBy: delta}
-	}
-	// Nbf has been reached. valid.
-	return nil
-}
-
-// ValidateAudience verifies that aud contains the audience value provided
-// by the WithAudience option.
-// Per the spec (https://tools.ietf.org/html/rfc7519#section-4.1.3), if the aud
-// claim is present,
-func (h *ValidationHelper) ValidateAudience(aud ClaimStrings) error {
-	// Skip flag
-	if h.skipAudience {
-		return nil
-	}
-
-	// If there's no audience claim, ignore
-	if aud == nil || len(aud) == 0 {
-		return nil
-	}
-
-	// If there is an audience claim, but no value provided, fail
-	if h.audience == nil {
-		return &InvalidAudienceError{Message: "audience value was expected but not provided"}
-	}
-
-	return h.ValidateAudienceAgainst(aud, *h.audience)
-}
-
-// ValidateAudienceAgainst checks that the compare value is included in the aud list
-// It is used by ValidateAudience, but exposed as a helper for other implementations
-func (h *ValidationHelper) ValidateAudienceAgainst(aud ClaimStrings, compare string) error {
-	if aud == nil {
-		return nil
-	}
-
-	// Compare provided value with aud claim.
-	// This code avoids the early return to make this check more or less constant time.
-	// I'm not certain that's actually required in this context.
-	var match = false
-	for _, audStr := range aud {
-		if subtle.ConstantTimeCompare([]byte(audStr), []byte(compare)) == 1 {
-			match = true
-		}
-	}
-	if !match {
-		return &InvalidAudienceError{Message: fmt.Sprintf("'%v' wasn't found in aud claim", compare)}
-	}
-	return nil
-
-}
-
-// ValidateIssuer checks the claim value against the value provided by WithIssuer
-func (h *ValidationHelper) ValidateIssuer(iss string) error {
-	// Always passes validation if issuer is not provided
-	if h.issuer == nil {
-		return nil
-	}
-
-	return h.ValidateIssuerAgainst(iss, *h.issuer)
-}
-
-// ValidateIssuerAgainst checks the claim value against the value provided, ignoring the WithIssuer value
-func (h *ValidationHelper) ValidateIssuerAgainst(iss string, compare string) error {
-	if subtle.ConstantTimeCompare([]byte(iss), []byte(compare)) == 1 {
-		return nil
-	}
-
-	return &InvalidIssuerError{Message: "'iss' value doesn't match expectation"}
-}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/.gitignore b/vendor/github.com/form3tech-oss/jwt-go/.gitignore
similarity index 69%
rename from vendor/github.com/dgrijalva/jwt-go/v4/.gitignore
rename to vendor/github.com/form3tech-oss/jwt-go/.gitignore
index 80bed65..c0e81a8 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/.gitignore
+++ b/vendor/github.com/form3tech-oss/jwt-go/.gitignore
@@ -1,4 +1,5 @@
 .DS_Store
 bin
+.idea/
 
 
diff --git a/vendor/github.com/form3tech-oss/jwt-go/.travis.yml b/vendor/github.com/form3tech-oss/jwt-go/.travis.yml
new file mode 100644
index 0000000..3c7fb7e
--- /dev/null
+++ b/vendor/github.com/form3tech-oss/jwt-go/.travis.yml
@@ -0,0 +1,12 @@
+language: go
+
+script:
+    - go vet ./...
+    - go test -v ./...
+
+go:
+  - 1.12
+  - 1.13
+  - 1.14
+  - 1.15
+  - tip
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/LICENSE b/vendor/github.com/form3tech-oss/jwt-go/LICENSE
similarity index 100%
rename from vendor/github.com/dgrijalva/jwt-go/v4/LICENSE
rename to vendor/github.com/form3tech-oss/jwt-go/LICENSE
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/MIGRATION_GUIDE.md b/vendor/github.com/form3tech-oss/jwt-go/MIGRATION_GUIDE.md
similarity index 97%
rename from vendor/github.com/dgrijalva/jwt-go/v4/MIGRATION_GUIDE.md
rename to vendor/github.com/form3tech-oss/jwt-go/MIGRATION_GUIDE.md
index 343afd8..7fc1f79 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/MIGRATION_GUIDE.md
+++ b/vendor/github.com/form3tech-oss/jwt-go/MIGRATION_GUIDE.md
@@ -1,7 +1,3 @@
-## Migration Guide from v3 -> v4
-
-TODO: write this
-
 ## Migration Guide from v2 -> v3
 
 Version 3 adds several new, frequently requested features.  To do so, it introduces a few breaking changes.  We've worked to keep these as minimal as possible.  This guide explains the breaking changes and how you can quickly update your code.
@@ -86,7 +82,7 @@ To replace this behavior, we've added two helper methods: `ParseRSAPrivateKeyFro
 	func keyLookupFunc(*Token) (interface{}, error) {
 		// Don't forget to validate the alg is what you expect:
 		if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
-			return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
+			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
 		}
 		
 		// Look up key 
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/README.md b/vendor/github.com/form3tech-oss/jwt-go/README.md
similarity index 58%
rename from vendor/github.com/dgrijalva/jwt-go/v4/README.md
rename to vendor/github.com/form3tech-oss/jwt-go/README.md
index 230589b..d774907 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/README.md
+++ b/vendor/github.com/form3tech-oss/jwt-go/README.md
@@ -5,37 +5,37 @@
 
 A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html)
 
-**NEW VERSION:** Version 4 of this library is now available. This is the first non-backward-compatible version in a long time. There are a few changes that all users will notice, such as the new types introduced in members of `StandardClaims`. More changes are additive or only impact more advanced use. See VERSION_HISTORY.md for a list of changes as well as **TODO** MIGRATION_GUIDE.md for help updating your code.
+**NEW VERSION COMING:** There have been a lot of improvements suggested since the version 3.0.0 released in 2016. I'm working now on cutting two different releases: 3.2.0 will contain any non-breaking changes or enhancements. 4.0.0 will follow shortly which will include breaking changes. See the 4.0.0 milestone to get an idea of what's coming. If you have other ideas, or would like to participate in 4.0.0, now's the time. If you depend on this library and don't want to be interrupted, I recommend you use your dependency mangement tool to pin to version 3. 
 
 **SECURITY NOTICE:** Some older versions of Go have a security issue in the cryotp/elliptic. Recommendation is to upgrade to at least 1.8.3. See issue #216 for more detail.
 
-**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided.
+**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage.  See the examples provided.
 
 ## What the heck is a JWT?
 
 JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web Tokens.
 
-In short, it's a signed JSON object that does something useful (for example, authentication). It's commonly used for `Bearer` tokens in Oauth 2. A token is made of three parts, separated by `.`'s. The first two parts are JSON objects, that have been [base64url](http://tools.ietf.org/html/rfc4648) encoded. The last part is the signature, encoded the same way.
+In short, it's a signed JSON object that does something useful (for example, authentication).  It's commonly used for `Bearer` tokens in Oauth 2.  A token is made of three parts, separated by `.`'s.  The first two parts are JSON objects, that have been [base64url](http://tools.ietf.org/html/rfc4648) encoded.  The last part is the signature, encoded the same way.
 
-The first part is called the header. It contains the necessary information for verifying the last part, the signature. For example, which encryption method was used for signing and what key was used.
+The first part is called the header.  It contains the necessary information for verifying the last part, the signature.  For example, which encryption method was used for signing and what key was used.
 
-The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [the RFC](http://self-issued.info/docs/draft-jones-json-web-token.html) for information about reserved keys and the proper way to add your own.
+The part in the middle is the interesting bit.  It's called the Claims and contains the actual stuff you care about.  Refer to [the RFC](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html) for information about reserved keys and the proper way to add your own.
 
 ## What's in the box?
 
-This library supports the parsing and verification as well as the generation and signing of JWTs. Current supported signing algorithms are HMAC SHA, RSA, RSA-PSS, and ECDSA, though hooks are present for adding your own.
+This library supports the parsing and verification as well as the generation and signing of JWTs.  Current supported signing algorithms are HMAC SHA, RSA, RSA-PSS, and ECDSA, though hooks are present for adding your own.
 
 ## Examples
 
 See [the project documentation](https://godoc.org/github.com/dgrijalva/jwt-go) for examples of usage:
 
-- [Simple example of parsing and validating a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac)
-- [Simple example of building and signing a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac)
-- [Directory of Examples](https://godoc.org/github.com/dgrijalva/jwt-go#pkg-examples)
+* [Simple example of parsing and validating a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac)
+* [Simple example of building and signing a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac)
+* [Directory of Examples](https://godoc.org/github.com/dgrijalva/jwt-go#pkg-examples)
 
 ## Extensions
 
-This library publishes all the necessary components for adding your own signing methods. Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`.
+This library publishes all the necessary components for adding your own signing methods.  Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`.  
 
 Here's an example of an extension that integrates with multiple Google Cloud Platform signing tools (AppEngine, IAM API, Cloud KMS): https://github.com/someone1/gcp-jwt-go
 
@@ -43,19 +43,18 @@ Here's an example of an extension that integrates with multiple Google Cloud Pla
 
 This library was last reviewed to comply with [RTF 7519](http://www.rfc-editor.org/info/rfc7519) dated May 2015 with a few notable differences:
 
-- In order to protect against accidental use of [Unsecured JWTs](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#UnsecuredJWT), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key.
+* In order to protect against accidental use of [Unsecured JWTs](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#UnsecuredJWT), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key.
 
 ## Project Status & Versioning
 
-This library is considered production ready. Feedback and feature requests are appreciated. The API should be considered stable. There should be very few backwards-incompatible changes outside of major version updates (and only with good reason).
+This library is considered production ready.  Feedback and feature requests are appreciated.  The API should be considered stable.  There should be very few backwards-incompatible changes outside of major version updates (and only with good reason).
 
-This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull requests will land on `master`. Periodically, versions will be tagged from `master`. You can find all the releases on [the project releases page](https://github.com/dgrijalva/jwt-go/releases).
+This project uses [Semantic Versioning 2.0.0](http://semver.org).  Accepted pull requests will land on `master`.  Periodically, versions will be tagged from `master`.  You can find all the releases on [the project releases page](https://github.com/dgrijalva/jwt-go/releases).
 
-As of version 4, this project is compatible with go modules. You should use that to ensure you have no unpleasant surprises when updating.
+While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users.  You may want to use this alternative package include: `gopkg.in/dgrijalva/jwt-go.v3`.  It will do the right thing WRT semantic versioning.
 
-**BREAKING CHANGES:\***
-
-- Version 4.0.0 includes _a lot_ of changes from the 3.x line, including a few that break the API. We've tried to break as few things as possible, so there should just be a few type signature changes. A full list of breaking changes is available in `VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating your code.
+**BREAKING CHANGES:*** 
+* Version 3.0.0 includes _a lot_ of changes from the 2.x line, including a few that break the API.  We've tried to break as few things as possible, so there should just be a few type signature changes.  A full list of breaking changes is available in `VERSION_HISTORY.md`.  See `MIGRATION_GUIDE.md` for more information on updating your code.
 
 ## Usage Tips
 
@@ -63,14 +62,14 @@ As of version 4, this project is compatible with go modules. You should use that
 
 A token is simply a JSON object that is signed by its author. this tells you exactly two things about the data:
 
-- The author of the token was in the possession of the signing secret
-- The data has not been modified since it was signed
+* The author of the token was in the possession of the signing secret
+* The data has not been modified since it was signed
 
 It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, `JWE`, that provides this functionality. JWE is currently outside the scope of this library.
 
 ### Choosing a Signing Method
 
-There are several signing methods available, and you should probably take the time to learn about the various options before choosing one. The principal design decision is most likely going to be symmetric vs asymmetric.
+There are several signing methods available, and you should probably take the time to learn about the various options before choosing one.  The principal design decision is most likely going to be symmetric vs asymmetric.
 
 Symmetric signing methods, such as HSA, use only a single secret. This is probably the simplest signing method to use since any `[]byte` can be used as a valid secret. They are also slightly computationally faster to use, though this rarely is enough to matter. Symmetric signing methods work the best when both producers and consumers of tokens are trusted, or even the same system. Since the same secret is used to both sign and validate tokens, you can't easily distribute the key for validation.
 
@@ -80,9 +79,9 @@ Asymmetric signing methods, such as RSA, use different keys for signing and veri
 
 Each signing method expects a different object type for its signing keys. See the package documentation for details. Here are the most common ones:
 
-- The [HMAC signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation
-- The [RSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation
-- The [ECDSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation
+* The [HMAC signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation
+* The [RSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation
+* The [ECDSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation
 
 ### JWT and OAuth
 
@@ -90,9 +89,13 @@ It's worth mentioning that OAuth and JWT are not the same thing. A JWT token is
 
 Without going too far down the rabbit hole, here's a description of the interaction of these technologies:
 
-- OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth.
-- OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token.
-- Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL.
+* OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth.
+* OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token.
+* Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL.
+
+### Troubleshooting
+
+This library uses descriptive error messages whenever possible. If you are not getting the expected result, have a look at the errors. The most common place people get stuck is providing the correct type of key to the parser. See the above section on signing methods and key types.
 
 ## More
 
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/VERSION_HISTORY.md b/vendor/github.com/form3tech-oss/jwt-go/VERSION_HISTORY.md
similarity index 69%
rename from vendor/github.com/dgrijalva/jwt-go/v4/VERSION_HISTORY.md
rename to vendor/github.com/form3tech-oss/jwt-go/VERSION_HISTORY.md
index fffaa37..6370298 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/VERSION_HISTORY.md
+++ b/vendor/github.com/form3tech-oss/jwt-go/VERSION_HISTORY.md
@@ -1,28 +1,5 @@
 ## `jwt-go` Version History
 
-#### 4.0.0
-
-* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code 
-    * Errors have been updated significantly to take advantage of the changes to errors in go1.13/go2/xerrors
-        * The previous 'enum' describing error types has been replaced with unique types for every kind of error
-        * The new error types carry more information and interoperate properly with errors.As
-    * Dropping (official) support for go1.10 or older. Older versions dating back to 1.4 **may** continue to work, but are not being considered or tested against. 1.3 and previous will no longer work with this library.
-    * Behavior of time values has changed significantly, primarily to handle nil values, but also to be more consistent with Go:
-        * All time values used by the library are expressed using time.Time and time.Duration. This includes automatic parsing and encoding of the JWT unix timestamp format. 
-        * `StandardClaims` time values use the new `Time` type, which wraps time.Time to handle things nil values gracefully
-    * The method for describing custom parsing/validating behaviors has changed. The properties exposed on Parser have been replaced with `ParserOption`s. See https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis for the theory. See `ParserOption` and `SigningOption` for more details
-    * Per the spec, if the `aud` claim is present, it will be automatically validated. See `WithAudience` and `WithoutAudienceValidation`
-    * The `Valid` method on `Claims` now takes an argument, `ValidationHelper`.
-* Added support for Leeway. If you have issues with clock sku between the issuing machine and the consuming machine, you can allow for a grace period. See `WithLeeway`
-* Added support for custom JSON encoder/decoders. See `WithMarshaller` and `WithUnmarshaller`
-* Added support for issuer validation. See `WithIssuer`
-* Updated error messages and comments to comply with linter recommendations
-* Added `KnownKeyfunc` for when you know both the signing method and the key without needing to look at the token Header. This should dramatically simplify many common use cases.
-* Added `ValidationHelper` to make it easier to implement custom Claims types without having to rewrite a bunch of built-in behavior, such as time comparison and leeway. `ValidationHelper` is built with `ParserOptions` and provides the same methods used by built in claims types to handle validation.
-* Added support for `crypto.Signer` on several signing methods. This was a common request.
-* Added new type, `ClaimStrings`, which will correctly handle properties such as `aud` that can be either an array of strings or a single string. `ClaimStrings` is an alias to `[]string`, but with custom decoding behavior. This means all the built in `aud` validation behavior now expects `[]string` instead of `string`. This was a common request.
-
-
 #### 3.2.0
 
 * Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation
diff --git a/vendor/github.com/form3tech-oss/jwt-go/claims.go b/vendor/github.com/form3tech-oss/jwt-go/claims.go
new file mode 100644
index 0000000..6248906
--- /dev/null
+++ b/vendor/github.com/form3tech-oss/jwt-go/claims.go
@@ -0,0 +1,136 @@
+package jwt
+
+import (
+	"crypto/subtle"
+	"fmt"
+	"time"
+)
+
+// For a type to be a Claims object, it must just have a Valid method that determines
+// if the token is invalid for any supported reason
+type Claims interface {
+	Valid() error
+}
+
+// Structured version of Claims Section, as referenced at
+// https://tools.ietf.org/html/rfc7519#section-4.1
+// See examples for how to use this with your own claim types
+type StandardClaims struct {
+	Audience  []string `json:"aud,omitempty"`
+	ExpiresAt int64  `json:"exp,omitempty"`
+	Id        string `json:"jti,omitempty"`
+	IssuedAt  int64  `json:"iat,omitempty"`
+	Issuer    string `json:"iss,omitempty"`
+	NotBefore int64  `json:"nbf,omitempty"`
+	Subject   string `json:"sub,omitempty"`
+}
+
+// Validates time based claims "exp, iat, nbf".
+// There is no accounting for clock skew.
+// As well, if any of the above claims are not in the token, it will still
+// be considered a valid claim.
+func (c StandardClaims) Valid() error {
+	vErr := new(ValidationError)
+	now := TimeFunc().Unix()
+
+	// The claims below are optional, by default, so if they are set to the
+	// default value in Go, let's not fail the verification for them.
+	if c.VerifyExpiresAt(now, false) == false {
+		delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0))
+		vErr.Inner = fmt.Errorf("token is expired by %v", delta)
+		vErr.Errors |= ValidationErrorExpired
+	}
+
+	if c.VerifyIssuedAt(now, false) == false {
+		vErr.Inner = fmt.Errorf("Token used before issued")
+		vErr.Errors |= ValidationErrorIssuedAt
+	}
+
+	if c.VerifyNotBefore(now, false) == false {
+		vErr.Inner = fmt.Errorf("token is not valid yet")
+		vErr.Errors |= ValidationErrorNotValidYet
+	}
+
+	if vErr.valid() {
+		return nil
+	}
+
+	return vErr
+}
+
+// Compares the aud claim against cmp.
+// If required is false, this method will return true if the value matches or is unset
+func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool {
+	return verifyAud(c.Audience, cmp, req)
+}
+
+// Compares the exp claim against cmp.
+// If required is false, this method will return true if the value matches or is unset
+func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool {
+	return verifyExp(c.ExpiresAt, cmp, req)
+}
+
+// Compares the iat claim against cmp.
+// If required is false, this method will return true if the value matches or is unset
+func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool {
+	return verifyIat(c.IssuedAt, cmp, req)
+}
+
+// Compares the iss claim against cmp.
+// If required is false, this method will return true if the value matches or is unset
+func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool {
+	return verifyIss(c.Issuer, cmp, req)
+}
+
+// Compares the nbf claim against cmp.
+// If required is false, this method will return true if the value matches or is unset
+func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {
+	return verifyNbf(c.NotBefore, cmp, req)
+}
+
+// ----- helpers
+
+func verifyAud(aud []string, cmp string, required bool) bool {
+	if len(aud) == 0 {
+		return !required
+	}
+
+	for _, a := range aud {
+		if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 {
+			return true
+		}
+	}
+	return false
+}
+
+func verifyExp(exp int64, now int64, required bool) bool {
+	if exp == 0 {
+		return !required
+	}
+	return now <= exp
+}
+
+func verifyIat(iat int64, now int64, required bool) bool {
+	if iat == 0 {
+		return !required
+	}
+	return now >= iat
+}
+
+func verifyIss(iss string, cmp string, required bool) bool {
+	if iss == "" {
+		return !required
+	}
+	if subtle.ConstantTimeCompare([]byte(iss), []byte(cmp)) != 0 {
+		return true
+	} else {
+		return false
+	}
+}
+
+func verifyNbf(nbf int64, now int64, required bool) bool {
+	if nbf == 0 {
+		return !required
+	}
+	return now >= nbf
+}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/doc.go b/vendor/github.com/form3tech-oss/jwt-go/doc.go
similarity index 100%
rename from vendor/github.com/dgrijalva/jwt-go/v4/doc.go
rename to vendor/github.com/form3tech-oss/jwt-go/doc.go
diff --git a/vendor/github.com/form3tech-oss/jwt-go/ecdsa.go b/vendor/github.com/form3tech-oss/jwt-go/ecdsa.go
new file mode 100644
index 0000000..f977381
--- /dev/null
+++ b/vendor/github.com/form3tech-oss/jwt-go/ecdsa.go
@@ -0,0 +1,148 @@
+package jwt
+
+import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/rand"
+	"errors"
+	"math/big"
+)
+
+var (
+	// Sadly this is missing from crypto/ecdsa compared to crypto/rsa
+	ErrECDSAVerification = errors.New("crypto/ecdsa: verification error")
+)
+
+// Implements the ECDSA family of signing methods signing methods
+// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification
+type SigningMethodECDSA struct {
+	Name      string
+	Hash      crypto.Hash
+	KeySize   int
+	CurveBits int
+}
+
+// Specific instances for EC256 and company
+var (
+	SigningMethodES256 *SigningMethodECDSA
+	SigningMethodES384 *SigningMethodECDSA
+	SigningMethodES512 *SigningMethodECDSA
+)
+
+func init() {
+	// ES256
+	SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256}
+	RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod {
+		return SigningMethodES256
+	})
+
+	// ES384
+	SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384}
+	RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod {
+		return SigningMethodES384
+	})
+
+	// ES512
+	SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521}
+	RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod {
+		return SigningMethodES512
+	})
+}
+
+func (m *SigningMethodECDSA) Alg() string {
+	return m.Name
+}
+
+// Implements the Verify method from SigningMethod
+// For this verify method, key must be an ecdsa.PublicKey struct
+func (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error {
+	var err error
+
+	// Decode the signature
+	var sig []byte
+	if sig, err = DecodeSegment(signature); err != nil {
+		return err
+	}
+
+	// Get the key
+	var ecdsaKey *ecdsa.PublicKey
+	switch k := key.(type) {
+	case *ecdsa.PublicKey:
+		ecdsaKey = k
+	default:
+		return ErrInvalidKeyType
+	}
+
+	if len(sig) != 2*m.KeySize {
+		return ErrECDSAVerification
+	}
+
+	r := big.NewInt(0).SetBytes(sig[:m.KeySize])
+	s := big.NewInt(0).SetBytes(sig[m.KeySize:])
+
+	// Create hasher
+	if !m.Hash.Available() {
+		return ErrHashUnavailable
+	}
+	hasher := m.Hash.New()
+	hasher.Write([]byte(signingString))
+
+	// Verify the signature
+	if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus == true {
+		return nil
+	} else {
+		return ErrECDSAVerification
+	}
+}
+
+// Implements the Sign method from SigningMethod
+// For this signing method, key must be an ecdsa.PrivateKey struct
+func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) {
+	// Get the key
+	var ecdsaKey *ecdsa.PrivateKey
+	switch k := key.(type) {
+	case *ecdsa.PrivateKey:
+		ecdsaKey = k
+	default:
+		return "", ErrInvalidKeyType
+	}
+
+	// Create the hasher
+	if !m.Hash.Available() {
+		return "", ErrHashUnavailable
+	}
+
+	hasher := m.Hash.New()
+	hasher.Write([]byte(signingString))
+
+	// Sign the string and return r, s
+	if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil {
+		curveBits := ecdsaKey.Curve.Params().BitSize
+
+		if m.CurveBits != curveBits {
+			return "", ErrInvalidKey
+		}
+
+		keyBytes := curveBits / 8
+		if curveBits%8 > 0 {
+			keyBytes += 1
+		}
+
+		// We serialize the outpus (r and s) into big-endian byte arrays and pad
+		// them with zeros on the left to make sure the sizes work out. Both arrays
+		// must be keyBytes long, and the output must be 2*keyBytes long.
+		rBytes := r.Bytes()
+		rBytesPadded := make([]byte, keyBytes)
+		copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
+
+		sBytes := s.Bytes()
+		sBytesPadded := make([]byte, keyBytes)
+		copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
+
+		out := append(rBytesPadded, sBytesPadded...)
+
+		return EncodeSegment(out), nil
+	} else {
+		return "", err
+	}
+}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/ecdsa_utils.go b/vendor/github.com/form3tech-oss/jwt-go/ecdsa_utils.go
similarity index 74%
rename from vendor/github.com/dgrijalva/jwt-go/v4/ecdsa_utils.go
rename to vendor/github.com/form3tech-oss/jwt-go/ecdsa_utils.go
index 627e7db..db9f4be 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/ecdsa_utils.go
+++ b/vendor/github.com/form3tech-oss/jwt-go/ecdsa_utils.go
@@ -7,14 +7,12 @@ import (
 	"errors"
 )
 
-// Errors returned by EC signing methods
 var (
-	ErrNotECPublicKey  = errors.New("key is not a valid ECDSA public key")
-	ErrNotECPrivateKey = errors.New("key is not a valid ECDSA private key")
+	ErrNotECPublicKey  = errors.New("Key is not a valid ECDSA public key")
+	ErrNotECPrivateKey = errors.New("Key is not a valid ECDSA private key")
 )
 
-// ParseECPrivateKeyFromPEM is a helper function for
-// parsing a PEM encoded Elliptic Curve Private Key Structure
+// Parse PEM encoded Elliptic Curve Private Key Structure
 func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
 	var err error
 
@@ -27,7 +25,9 @@ func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
 	// Parse the key
 	var parsedKey interface{}
 	if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
-		return nil, err
+		if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
+			return nil, err
+		}
 	}
 
 	var pkey *ecdsa.PrivateKey
@@ -39,8 +39,7 @@ func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
 	return pkey, nil
 }
 
-// ParseECPublicKeyFromPEM is a helper function for
-// parsing a PEM encoded PKCS1 or PKCS8 public key
+// Parse PEM encoded PKCS1 or PKCS8 public key
 func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
 	var err error
 
diff --git a/vendor/github.com/form3tech-oss/jwt-go/errors.go b/vendor/github.com/form3tech-oss/jwt-go/errors.go
new file mode 100644
index 0000000..1c93024
--- /dev/null
+++ b/vendor/github.com/form3tech-oss/jwt-go/errors.go
@@ -0,0 +1,59 @@
+package jwt
+
+import (
+	"errors"
+)
+
+// Error constants
+var (
+	ErrInvalidKey      = errors.New("key is invalid")
+	ErrInvalidKeyType  = errors.New("key is of invalid type")
+	ErrHashUnavailable = errors.New("the requested hash function is unavailable")
+)
+
+// The errors that might occur when parsing and validating a token
+const (
+	ValidationErrorMalformed        uint32 = 1 << iota // Token is malformed
+	ValidationErrorUnverifiable                        // Token could not be verified because of signing problems
+	ValidationErrorSignatureInvalid                    // Signature validation failed
+
+	// Standard Claim validation errors
+	ValidationErrorAudience      // AUD validation failed
+	ValidationErrorExpired       // EXP validation failed
+	ValidationErrorIssuedAt      // IAT validation failed
+	ValidationErrorIssuer        // ISS validation failed
+	ValidationErrorNotValidYet   // NBF validation failed
+	ValidationErrorId            // JTI validation failed
+	ValidationErrorClaimsInvalid // Generic claims validation error
+)
+
+// Helper for constructing a ValidationError with a string error message
+func NewValidationError(errorText string, errorFlags uint32) *ValidationError {
+	return &ValidationError{
+		text:   errorText,
+		Errors: errorFlags,
+	}
+}
+
+// The error from Parse if token is not valid
+type ValidationError struct {
+	Inner  error  // stores the error returned by external dependencies, i.e.: KeyFunc
+	Errors uint32 // bitfield.  see ValidationError... constants
+	text   string // errors that do not have a valid error just have text
+}
+
+// Validation error is an error type
+func (e ValidationError) Error() string {
+	if e.Inner != nil {
+		return e.Inner.Error()
+	} else if e.text != "" {
+		return e.text
+	} else {
+		return "token is invalid"
+	}
+}
+
+// No errors
+func (e *ValidationError) valid() bool {
+	return e.Errors == 0
+}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/hmac.go b/vendor/github.com/form3tech-oss/jwt-go/hmac.go
similarity index 80%
rename from vendor/github.com/dgrijalva/jwt-go/v4/hmac.go
rename to vendor/github.com/form3tech-oss/jwt-go/hmac.go
index 2c91012..addbe5d 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/hmac.go
+++ b/vendor/github.com/form3tech-oss/jwt-go/hmac.go
@@ -6,7 +6,7 @@ import (
 	"errors"
 )
 
-// SigningMethodHMAC implements the HMAC-SHA family of signing methods
+// Implements the HMAC-SHA family of signing methods signing methods
 // Expects key type of []byte for both signing and validation
 type SigningMethodHMAC struct {
 	Name string
@@ -41,7 +41,6 @@ func init() {
 	})
 }
 
-// Alg implements SigningMethod
 func (m *SigningMethodHMAC) Alg() string {
 	return m.Name
 }
@@ -51,7 +50,7 @@ func (m *SigningMethodHMAC) Verify(signingString, signature string, key interfac
 	// Verify the key is the right type
 	keyBytes, ok := key.([]byte)
 	if !ok {
-		return NewInvalidKeyTypeError("[]byte", key)
+		return ErrInvalidKeyType
 	}
 
 	// Decode signature, for comparison
@@ -78,20 +77,19 @@ func (m *SigningMethodHMAC) Verify(signingString, signature string, key interfac
 	return nil
 }
 
-// Sign implements the Sign method from SigningMethod
+// Implements the Sign method from SigningMethod for this signing method.
 // Key must be []byte
 func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) {
-	keyBytes, ok := key.([]byte)
-	if !ok {
-		return "", NewInvalidKeyTypeError("[]byte", key)
-	}
+	if keyBytes, ok := key.([]byte); ok {
+		if !m.Hash.Available() {
+			return "", ErrHashUnavailable
+		}
 
-	if !m.Hash.Available() {
-		return "", ErrHashUnavailable
-	}
+		hasher := hmac.New(m.Hash.New, keyBytes)
+		hasher.Write([]byte(signingString))
 
-	hasher := hmac.New(m.Hash.New, keyBytes)
-	hasher.Write([]byte(signingString))
+		return EncodeSegment(hasher.Sum(nil)), nil
+	}
 
-	return EncodeSegment(hasher.Sum(nil)), nil
+	return "", ErrInvalidKeyType
 }
diff --git a/vendor/github.com/form3tech-oss/jwt-go/map_claims.go b/vendor/github.com/form3tech-oss/jwt-go/map_claims.go
new file mode 100644
index 0000000..90ab6be
--- /dev/null
+++ b/vendor/github.com/form3tech-oss/jwt-go/map_claims.go
@@ -0,0 +1,102 @@
+package jwt
+
+import (
+	"encoding/json"
+	"errors"
+	// "fmt"
+)
+
+// Claims type that uses the map[string]interface{} for JSON decoding
+// This is the default claims type if you don't supply one
+type MapClaims map[string]interface{}
+
+// Compares the aud claim against cmp.
+// If required is false, this method will return true if the value matches or is unset
+func (m MapClaims) VerifyAudience(cmp string, req bool) bool {
+	aud, ok := m["aud"].([]string)
+	if !ok {
+		strAud, ok := m["aud"].(string)
+		if !ok {
+			return false
+		}
+		aud = append(aud, strAud)
+	}
+
+	return verifyAud(aud, cmp, req)
+}
+
+// Compares the exp claim against cmp.
+// If required is false, this method will return true if the value matches or is unset
+func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool {
+	switch exp := m["exp"].(type) {
+	case float64:
+		return verifyExp(int64(exp), cmp, req)
+	case json.Number:
+		v, _ := exp.Int64()
+		return verifyExp(v, cmp, req)
+	}
+	return req == false
+}
+
+// Compares the iat claim against cmp.
+// If required is false, this method will return true if the value matches or is unset
+func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool {
+	switch iat := m["iat"].(type) {
+	case float64:
+		return verifyIat(int64(iat), cmp, req)
+	case json.Number:
+		v, _ := iat.Int64()
+		return verifyIat(v, cmp, req)
+	}
+	return req == false
+}
+
+// Compares the iss claim against cmp.
+// If required is false, this method will return true if the value matches or is unset
+func (m MapClaims) VerifyIssuer(cmp string, req bool) bool {
+	iss, _ := m["iss"].(string)
+	return verifyIss(iss, cmp, req)
+}
+
+// Compares the nbf claim against cmp.
+// If required is false, this method will return true if the value matches or is unset
+func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool {
+	switch nbf := m["nbf"].(type) {
+	case float64:
+		return verifyNbf(int64(nbf), cmp, req)
+	case json.Number:
+		v, _ := nbf.Int64()
+		return verifyNbf(v, cmp, req)
+	}
+	return req == false
+}
+
+// Validates time based claims "exp, iat, nbf".
+// There is no accounting for clock skew.
+// As well, if any of the above claims are not in the token, it will still
+// be considered a valid claim.
+func (m MapClaims) Valid() error {
+	vErr := new(ValidationError)
+	now := TimeFunc().Unix()
+
+	if m.VerifyExpiresAt(now, false) == false {
+		vErr.Inner = errors.New("Token is expired")
+		vErr.Errors |= ValidationErrorExpired
+	}
+
+	if m.VerifyIssuedAt(now, false) == false {
+		vErr.Inner = errors.New("Token used before issued")
+		vErr.Errors |= ValidationErrorIssuedAt
+	}
+
+	if m.VerifyNotBefore(now, false) == false {
+		vErr.Inner = errors.New("Token is not valid yet")
+		vErr.Errors |= ValidationErrorNotValidYet
+	}
+
+	if vErr.valid() {
+		return nil
+	}
+
+	return vErr
+}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/none.go b/vendor/github.com/form3tech-oss/jwt-go/none.go
similarity index 67%
rename from vendor/github.com/dgrijalva/jwt-go/v4/none.go
rename to vendor/github.com/form3tech-oss/jwt-go/none.go
index a5caed3..f04d189 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/none.go
+++ b/vendor/github.com/form3tech-oss/jwt-go/none.go
@@ -1,16 +1,11 @@
 package jwt
 
-// SigningMethodNone implements the none signing method.  This is required by the spec
+// Implements the none signing method.  This is required by the spec
 // but you probably should never use it.
 var SigningMethodNone *signingMethodNone
 
-// UnsafeAllowNoneSignatureType must be returned from Keyfunc in order for the
-// none signing method to be allowed. This is intended to make is possible to use
-// this signing method, but not by accident
 const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed"
 
-// NoneSignatureTypeDisallowedError is the error value returned when the none signing method
-// is used without UnsafeAllowNoneSignatureType
 var NoneSignatureTypeDisallowedError error
 
 type signingMethodNone struct{}
@@ -18,7 +13,7 @@ type unsafeNoneMagicConstant string
 
 func init() {
 	SigningMethodNone = &signingMethodNone{}
-	NoneSignatureTypeDisallowedError = &InvalidSignatureError{Message: "'none' signature type is not allowed"}
+	NoneSignatureTypeDisallowedError = NewValidationError("'none' signature type is not allowed", ValidationErrorSignatureInvalid)
 
 	RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod {
 		return SigningMethodNone
@@ -38,7 +33,10 @@ func (m *signingMethodNone) Verify(signingString, signature string, key interfac
 	}
 	// If signing method is none, signature must be an empty string
 	if signature != "" {
-		return &InvalidSignatureError{Message: "'none' signing method with non-empty signature"}
+		return NewValidationError(
+			"'none' signing method with non-empty signature",
+			ValidationErrorSignatureInvalid,
+		)
 	}
 
 	// Accept 'none' signing method.
diff --git a/vendor/github.com/form3tech-oss/jwt-go/parser.go b/vendor/github.com/form3tech-oss/jwt-go/parser.go
new file mode 100644
index 0000000..d6901d9
--- /dev/null
+++ b/vendor/github.com/form3tech-oss/jwt-go/parser.go
@@ -0,0 +1,148 @@
+package jwt
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"strings"
+)
+
+type Parser struct {
+	ValidMethods         []string // If populated, only these methods will be considered valid
+	UseJSONNumber        bool     // Use JSON Number format in JSON decoder
+	SkipClaimsValidation bool     // Skip claims validation during token parsing
+}
+
+// Parse, validate, and return a token.
+// keyFunc will receive the parsed token and should return the key for validating.
+// If everything is kosher, err will be nil
+func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
+	return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc)
+}
+
+func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
+	token, parts, err := p.ParseUnverified(tokenString, claims)
+	if err != nil {
+		return token, err
+	}
+
+	// Verify signing method is in the required set
+	if p.ValidMethods != nil {
+		var signingMethodValid = false
+		var alg = token.Method.Alg()
+		for _, m := range p.ValidMethods {
+			if m == alg {
+				signingMethodValid = true
+				break
+			}
+		}
+		if !signingMethodValid {
+			// signing method is not in the listed set
+			return token, NewValidationError(fmt.Sprintf("signing method %v is invalid", alg), ValidationErrorSignatureInvalid)
+		}
+	}
+
+	// Lookup key
+	var key interface{}
+	if keyFunc == nil {
+		// keyFunc was not provided.  short circuiting validation
+		return token, NewValidationError("no Keyfunc was provided.", ValidationErrorUnverifiable)
+	}
+	if key, err = keyFunc(token); err != nil {
+		// keyFunc returned an error
+		if ve, ok := err.(*ValidationError); ok {
+			return token, ve
+		}
+		return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable}
+	}
+
+	vErr := &ValidationError{}
+
+	// Validate Claims
+	if !p.SkipClaimsValidation {
+		if err := token.Claims.Valid(); err != nil {
+
+			// If the Claims Valid returned an error, check if it is a validation error,
+			// If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set
+			if e, ok := err.(*ValidationError); !ok {
+				vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid}
+			} else {
+				vErr = e
+			}
+		}
+	}
+
+	// Perform validation
+	token.Signature = parts[2]
+	if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil {
+		vErr.Inner = err
+		vErr.Errors |= ValidationErrorSignatureInvalid
+	}
+
+	if vErr.valid() {
+		token.Valid = true
+		return token, nil
+	}
+
+	return token, vErr
+}
+
+// WARNING: Don't use this method unless you know what you're doing
+//
+// This method parses the token but doesn't validate the signature. It's only
+// ever useful in cases where you know the signature is valid (because it has
+// been checked previously in the stack) and you want to extract values from
+// it.
+func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) {
+	parts = strings.Split(tokenString, ".")
+	if len(parts) != 3 {
+		return nil, parts, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed)
+	}
+
+	token = &Token{Raw: tokenString}
+
+	// parse Header
+	var headerBytes []byte
+	if headerBytes, err = DecodeSegment(parts[0]); err != nil {
+		if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") {
+			return token, parts, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed)
+		}
+		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
+	}
+	if err = json.Unmarshal(headerBytes, &token.Header); err != nil {
+		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
+	}
+
+	// parse Claims
+	var claimBytes []byte
+	token.Claims = claims
+
+	if claimBytes, err = DecodeSegment(parts[1]); err != nil {
+		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
+	}
+	dec := json.NewDecoder(bytes.NewBuffer(claimBytes))
+	if p.UseJSONNumber {
+		dec.UseNumber()
+	}
+	// JSON Decode.  Special case for map type to avoid weird pointer behavior
+	if c, ok := token.Claims.(MapClaims); ok {
+		err = dec.Decode(&c)
+	} else {
+		err = dec.Decode(&claims)
+	}
+	// Handle decode error
+	if err != nil {
+		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
+	}
+
+	// Lookup signature method
+	if method, ok := token.Header["alg"].(string); ok {
+		if token.Method = GetSigningMethod(method); token.Method == nil {
+			return token, parts, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable)
+		}
+	} else {
+		return token, parts, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable)
+	}
+
+	return token, parts, nil
+}
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/rsa.go b/vendor/github.com/form3tech-oss/jwt-go/rsa.go
similarity index 64%
rename from vendor/github.com/dgrijalva/jwt-go/v4/rsa.go
rename to vendor/github.com/form3tech-oss/jwt-go/rsa.go
index 72ba2d6..e4caf1c 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/rsa.go
+++ b/vendor/github.com/form3tech-oss/jwt-go/rsa.go
@@ -4,10 +4,9 @@ import (
 	"crypto"
 	"crypto/rand"
 	"crypto/rsa"
-	"fmt"
 )
 
-// SigningMethodRSA implements the RSA family of signing methods signing methods
+// Implements the RSA family of signing methods signing methods
 // Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation
 type SigningMethodRSA struct {
 	Name string
@@ -41,12 +40,11 @@ func init() {
 	})
 }
 
-// Alg implements the Alg method from SigningMethod
 func (m *SigningMethodRSA) Alg() string {
 	return m.Name
 }
 
-// Verify implements the Verify method from SigningMethod
+// Implements the Verify method from SigningMethod
 // For this signing method, must be an *rsa.PublicKey structure.
 func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error {
 	var err error
@@ -60,16 +58,8 @@ func (m *SigningMethodRSA) Verify(signingString, signature string, key interface
 	var rsaKey *rsa.PublicKey
 	var ok bool
 
-	switch k := key.(type) {
-	case *rsa.PublicKey:
-		rsaKey = k
-	case crypto.Signer:
-		pub := k.Public()
-		if rsaKey, ok = pub.(*rsa.PublicKey); !ok {
-			return &InvalidKeyError{Message: fmt.Sprintf("signer returned unexpected public key type: %T", pub)}
-		}
-	default:
-		return NewInvalidKeyTypeError("*rsa.PublicKey or crypto.Signer", key)
+	if rsaKey, ok = key.(*rsa.PublicKey); !ok {
+		return ErrInvalidKeyType
 	}
 
 	// Create hasher
@@ -83,19 +73,15 @@ func (m *SigningMethodRSA) Verify(signingString, signature string, key interface
 	return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig)
 }
 
-// Sign implements the Sign method from SigningMethod
+// Implements the Sign method from SigningMethod
 // For this signing method, must be an *rsa.PrivateKey structure.
 func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) {
-	var signer crypto.Signer
+	var rsaKey *rsa.PrivateKey
 	var ok bool
 
-	if signer, ok = key.(crypto.Signer); !ok {
-		return "", NewInvalidKeyTypeError("*rsa.PublicKey or crypto.Signer", key)
-	}
-
-	//sanity check that the signer is an rsa signer
-	if pub, ok := signer.Public().(*rsa.PublicKey); !ok {
-		return "", &InvalidKeyError{Message: fmt.Sprintf("signer returned unexpected public key type: %T", pub)}
+	// Validate type of key
+	if rsaKey, ok = key.(*rsa.PrivateKey); !ok {
+		return "", ErrInvalidKey
 	}
 
 	// Create the hasher
@@ -107,9 +93,9 @@ func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string,
 	hasher.Write([]byte(signingString))
 
 	// Sign the string and return the encoded bytes
-	sigBytes, err := signer.Sign(rand.Reader, hasher.Sum(nil), m.Hash)
-	if err != nil {
+	if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil {
+		return EncodeSegment(sigBytes), nil
+	} else {
 		return "", err
 	}
-	return EncodeSegment(sigBytes), nil
 }
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/rsa_pss.go b/vendor/github.com/form3tech-oss/jwt-go/rsa_pss.go
similarity index 57%
rename from vendor/github.com/dgrijalva/jwt-go/v4/rsa_pss.go
rename to vendor/github.com/form3tech-oss/jwt-go/rsa_pss.go
index aa3ba39..c014708 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/rsa_pss.go
+++ b/vendor/github.com/form3tech-oss/jwt-go/rsa_pss.go
@@ -6,16 +6,20 @@ import (
 	"crypto"
 	"crypto/rand"
 	"crypto/rsa"
-	"fmt"
 )
 
-// SigningMethodRSAPSS implements the RSAPSS family of signing methods
+// Implements the RSAPSS family of signing methods signing methods
 type SigningMethodRSAPSS struct {
 	*SigningMethodRSA
 	Options *rsa.PSSOptions
+	// VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS.
+	// Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow
+	// https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously.
+	// See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details.
+	VerifyOptions *rsa.PSSOptions
 }
 
-// Specific instances for RS/PS and company
+// Specific instances for RS/PS and company.
 var (
 	SigningMethodPS256 *SigningMethodRSAPSS
 	SigningMethodPS384 *SigningMethodRSAPSS
@@ -25,13 +29,15 @@ var (
 func init() {
 	// PS256
 	SigningMethodPS256 = &SigningMethodRSAPSS{
-		&SigningMethodRSA{
+		SigningMethodRSA: &SigningMethodRSA{
 			Name: "PS256",
 			Hash: crypto.SHA256,
 		},
-		&rsa.PSSOptions{
+		Options: &rsa.PSSOptions{
+			SaltLength: rsa.PSSSaltLengthEqualsHash,
+		},
+		VerifyOptions: &rsa.PSSOptions{
 			SaltLength: rsa.PSSSaltLengthAuto,
-			Hash:       crypto.SHA256,
 		},
 	}
 	RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod {
@@ -40,13 +46,15 @@ func init() {
 
 	// PS384
 	SigningMethodPS384 = &SigningMethodRSAPSS{
-		&SigningMethodRSA{
+		SigningMethodRSA: &SigningMethodRSA{
 			Name: "PS384",
 			Hash: crypto.SHA384,
 		},
-		&rsa.PSSOptions{
+		Options: &rsa.PSSOptions{
+			SaltLength: rsa.PSSSaltLengthEqualsHash,
+		},
+		VerifyOptions: &rsa.PSSOptions{
 			SaltLength: rsa.PSSSaltLengthAuto,
-			Hash:       crypto.SHA384,
 		},
 	}
 	RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod {
@@ -55,13 +63,15 @@ func init() {
 
 	// PS512
 	SigningMethodPS512 = &SigningMethodRSAPSS{
-		&SigningMethodRSA{
+		SigningMethodRSA: &SigningMethodRSA{
 			Name: "PS512",
 			Hash: crypto.SHA512,
 		},
-		&rsa.PSSOptions{
+		Options: &rsa.PSSOptions{
+			SaltLength: rsa.PSSSaltLengthEqualsHash,
+		},
+		VerifyOptions: &rsa.PSSOptions{
 			SaltLength: rsa.PSSSaltLengthAuto,
-			Hash:       crypto.SHA512,
 		},
 	}
 	RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod {
@@ -69,7 +79,7 @@ func init() {
 	})
 }
 
-// Verify implements the Verify method from SigningMethod
+// Implements the Verify method from SigningMethod
 // For this verify method, key must be an rsa.PublicKey struct
 func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interface{}) error {
 	var err error
@@ -81,18 +91,11 @@ func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interf
 	}
 
 	var rsaKey *rsa.PublicKey
-	var ok bool
-
 	switch k := key.(type) {
 	case *rsa.PublicKey:
 		rsaKey = k
-	case crypto.Signer:
-		pub := k.Public()
-		if rsaKey, ok = pub.(*rsa.PublicKey); !ok {
-			return &InvalidKeyError{Message: fmt.Sprintf("signer returned unexpected public key type: %T", pub)}
-		}
 	default:
-		return NewInvalidKeyTypeError("*rsa.PublicKey or crypto.Signer", key)
+		return ErrInvalidKey
 	}
 
 	// Create hasher
@@ -102,22 +105,24 @@ func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interf
 	hasher := m.Hash.New()
 	hasher.Write([]byte(signingString))
 
-	return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, m.Options)
+	opts := m.Options
+	if m.VerifyOptions != nil {
+		opts = m.VerifyOptions
+	}
+
+	return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts)
 }
 
-// Sign implements the Sign method from SigningMethod
+// Implements the Sign method from SigningMethod
 // For this signing method, key must be an rsa.PrivateKey struct
 func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) (string, error) {
-	var signer crypto.Signer
-	var ok bool
+	var rsaKey *rsa.PrivateKey
 
-	if signer, ok = key.(crypto.Signer); !ok {
-		return "", NewInvalidKeyTypeError("*rsa.PrivateKey or crypto.Signer", key)
-	}
-
-	//sanity check that the signer is an rsa signer
-	if pub, ok := signer.Public().(*rsa.PublicKey); !ok {
-		return "", &InvalidKeyError{Message: fmt.Sprintf("signer returned unexpected public key type: %T", pub)}
+	switch k := key.(type) {
+	case *rsa.PrivateKey:
+		rsaKey = k
+	default:
+		return "", ErrInvalidKeyType
 	}
 
 	// Create the hasher
@@ -129,10 +134,9 @@ func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) (strin
 	hasher.Write([]byte(signingString))
 
 	// Sign the string and return the encoded bytes
-	sigBytes, err := signer.Sign(rand.Reader, hasher.Sum(nil), m.Options)
-	if err != nil {
+	if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil {
+		return EncodeSegment(sigBytes), nil
+	} else {
 		return "", err
 	}
-	return EncodeSegment(sigBytes), nil
-
 }
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/rsa_utils.go b/vendor/github.com/form3tech-oss/jwt-go/rsa_utils.go
similarity index 76%
rename from vendor/github.com/dgrijalva/jwt-go/v4/rsa_utils.go
rename to vendor/github.com/form3tech-oss/jwt-go/rsa_utils.go
index b0dae4b..14c78c2 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/rsa_utils.go
+++ b/vendor/github.com/form3tech-oss/jwt-go/rsa_utils.go
@@ -7,15 +7,13 @@ import (
 	"errors"
 )
 
-// Errors returned by RSA Signing Method and helpers
 var (
-	ErrKeyMustBePEMEncoded = errors.New("invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
-	ErrNotRSAPrivateKey    = errors.New("key is not a valid RSA private key")
-	ErrNotRSAPublicKey     = errors.New("key is not a valid RSA public key")
+	ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be a PEM encoded PKCS1 or PKCS8 key")
+	ErrNotRSAPrivateKey    = errors.New("Key is not a valid RSA private key")
+	ErrNotRSAPublicKey     = errors.New("Key is not a valid RSA public key")
 )
 
-// ParseRSAPrivateKeyFromPEM is a helper method for
-// parsing PEM encoded PKCS1 or PKCS8 private key
+// Parse PEM encoded PKCS1 or PKCS8 private key
 func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
 	var err error
 
@@ -41,8 +39,7 @@ func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
 	return pkey, nil
 }
 
-// ParseRSAPrivateKeyFromPEMWithPassword is a helper method for
-// parsing PEM encoded PKCS1 or PKCS8 private key, encrypted with a password
+// Parse PEM encoded PKCS1 or PKCS8 private key protected with password
 func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) {
 	var err error
 
@@ -74,8 +71,7 @@ func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.Pr
 	return pkey, nil
 }
 
-// ParseRSAPublicKeyFromPEM is a helper method for
-// parsing a PEM encoded PKCS1 or PKCS8 public key
+// Parse PEM encoded PKCS1 or PKCS8 public key
 func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
 	var err error
 
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/signing_method.go b/vendor/github.com/form3tech-oss/jwt-go/signing_method.go
similarity index 71%
rename from vendor/github.com/dgrijalva/jwt-go/v4/signing_method.go
rename to vendor/github.com/form3tech-oss/jwt-go/signing_method.go
index 5e50243..ed1f212 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/signing_method.go
+++ b/vendor/github.com/form3tech-oss/jwt-go/signing_method.go
@@ -7,15 +7,14 @@ import (
 var signingMethods = map[string]func() SigningMethod{}
 var signingMethodLock = new(sync.RWMutex)
 
-// SigningMethod is the interface used for signing and verifying tokens
+// Implement SigningMethod to add new methods for signing or verifying tokens.
 type SigningMethod interface {
 	Verify(signingString, signature string, key interface{}) error // Returns nil if signature is valid
 	Sign(signingString string, key interface{}) (string, error)    // Returns encoded signature or error
 	Alg() string                                                   // returns the alg identifier for this method (example: 'HS256')
 }
 
-// RegisterSigningMethod stores the "alg" name and a factory function pair
-// used internally for looking up a signing method based on "alg".
+// Register the "alg" name and a factory function for signing method.
 // This is typically done during init() in the method's implementation
 func RegisterSigningMethod(alg string, f func() SigningMethod) {
 	signingMethodLock.Lock()
@@ -24,8 +23,7 @@ func RegisterSigningMethod(alg string, f func() SigningMethod) {
 	signingMethods[alg] = f
 }
 
-// GetSigningMethod returns the signing method registered by RegisterSigningMethod
-// This is used by the library internally during parsing and validation.
+// Get a signing method from an "alg" string
 func GetSigningMethod(alg string) (method SigningMethod) {
 	signingMethodLock.RLock()
 	defer signingMethodLock.RUnlock()
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/token.go b/vendor/github.com/form3tech-oss/jwt-go/token.go
similarity index 50%
rename from vendor/github.com/dgrijalva/jwt-go/v4/token.go
rename to vendor/github.com/form3tech-oss/jwt-go/token.go
index 5ab1eb5..d637e08 100644
--- a/vendor/github.com/dgrijalva/jwt-go/v4/token.go
+++ b/vendor/github.com/form3tech-oss/jwt-go/token.go
@@ -12,7 +12,13 @@ import (
 // server uses a different time zone than your tokens.
 var TimeFunc = time.Now
 
-// Token represents JWT Token.  Different fields will be used depending on whether you're
+// Parse methods use this callback function to supply
+// the key for verification.  The function receives the parsed,
+// but unverified Token.  This allows you to use properties in the
+// Header of the token (such as `kid`) to identify which key to use.
+type Keyfunc func(*Token) (interface{}, error)
+
+// A JWT Token.  Different fields will be used depending on whether you're
 // creating or parsing/verifying a token.
 type Token struct {
 	Raw       string                 // The raw token.  Populated when you Parse a token
@@ -23,12 +29,11 @@ type Token struct {
 	Valid     bool                   // Is the token valid?  Populated when you Parse/Verify a token
 }
 
-// New creates a new Token.  Takes a signing method. Uses the default claims type, MapClaims.
+// Create a new Token.  Takes a signing method
 func New(method SigningMethod) *Token {
 	return NewWithClaims(method, MapClaims{})
 }
 
-// NewWithClaims creats a new token with a specified signing method and claims type
 func NewWithClaims(method SigningMethod, claims Claims) *Token {
 	return &Token{
 		Header: map[string]interface{}{
@@ -40,11 +45,11 @@ func NewWithClaims(method SigningMethod, claims Claims) *Token {
 	}
 }
 
-// SignedString returns the complete, signed token
-func (t *Token) SignedString(key interface{}, opts ...SigningOption) (string, error) {
+// Get the complete, signed token
+func (t *Token) SignedString(key interface{}) (string, error) {
 	var sig, sstr string
 	var err error
-	if sstr, err = t.SigningString(opts...); err != nil {
+	if sstr, err = t.SigningString(); err != nil {
 		return "", err
 	}
 	if sig, err = t.Method.Sign(sstr, key); err != nil {
@@ -53,58 +58,51 @@ func (t *Token) SignedString(key interface{}, opts ...SigningOption) (string, er
 	return strings.Join([]string{sstr, sig}, "."), nil
 }
 
-// SigningString generates the signing string.  This is the
+// Generate the signing string.  This is the
 // most expensive part of the whole deal.  Unless you
 // need this for something special, just go straight for
 // the SignedString.
-func (t *Token) SigningString(opts ...SigningOption) (string, error) {
-	// Process options
-	var cfg = new(signingOptions)
-	for _, opt := range opts {
-		opt(cfg)
-	}
-	// Setup default marshaller
-	if cfg.marshaller == nil {
-		cfg.marshaller = t.defaultMarshaller
-	}
-
-	// Encode the two parts, then combine
-	inputParts := []interface{}{t.Header, t.Claims}
+func (t *Token) SigningString() (string, error) {
+	var err error
 	parts := make([]string, 2)
-	for i, v := range inputParts {
-		ctx := CodingContext{FieldDescriptor(i), t.Header}
-		jsonValue, err := cfg.marshaller(ctx, v)
-		if err != nil {
-			return "", err
+	for i, _ := range parts {
+		var jsonValue []byte
+		if i == 0 {
+			if jsonValue, err = json.Marshal(t.Header); err != nil {
+				return "", err
+			}
+		} else {
+			if jsonValue, err = json.Marshal(t.Claims); err != nil {
+				return "", err
+			}
 		}
+
 		parts[i] = EncodeSegment(jsonValue)
 	}
 	return strings.Join(parts, "."), nil
 }
 
-func (t *Token) defaultMarshaller(ctx CodingContext, v interface{}) ([]byte, error) {
-	return json.Marshal(v)
-}
-
-// Parse then validate, and return a token.
+// Parse, validate, and return a token.
 // keyFunc will receive the parsed token and should return the key for validating.
 // If everything is kosher, err will be nil
-// Claims type will be the default, MapClaims
-func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) {
-	return NewParser(options...).Parse(tokenString, keyFunc)
+func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
+	return new(Parser).Parse(tokenString, keyFunc)
 }
 
-// ParseWithClaims is Parse, but with a specified Claims type
-func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) {
-	return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc)
+func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
+	return new(Parser).ParseWithClaims(tokenString, claims, keyFunc)
 }
 
-// EncodeSegment is used internally for JWT specific base64url encoding with padding stripped
+// Encode JWT specific base64url encoding with padding stripped
 func EncodeSegment(seg []byte) string {
-	return base64.RawURLEncoding.EncodeToString(seg)
+	return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=")
 }
 
-// DecodeSegment is used internally for JWT specific base64url encoding with padding stripped
+// Decode JWT specific base64url encoding with padding stripped
 func DecodeSegment(seg string) ([]byte, error) {
-	return base64.RawURLEncoding.DecodeString(seg)
+	if l := len(seg) % 4; l > 0 {
+		seg += strings.Repeat("=", 4-l)
+	}
+
+	return base64.URLEncoding.DecodeString(seg)
 }
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 89efe5c..e427f4c 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -11,9 +11,9 @@ github.com/apache/arrow/go/arrow/internal/debug
 github.com/apache/arrow/go/arrow/internal/flatbuf
 github.com/apache/arrow/go/arrow/ipc
 github.com/apache/arrow/go/arrow/memory
-# github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1
+# github.com/form3tech-oss/jwt-go v3.2.2+incompatible
 ## explicit
-github.com/dgrijalva/jwt-go/v4
+github.com/form3tech-oss/jwt-go
 # github.com/google/flatbuffers v1.11.0
 github.com/google/flatbuffers/go
 # github.com/google/uuid v1.1.1


Test patch:
diff --git a/auth_test.go b/auth_test.go
index 6bc8b04..da309cf 100644
--- a/auth_test.go
+++ b/auth_test.go
@@ -9,7 +9,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"github.com/dgrijalva/jwt-go/v4"
+	"github.com/form3tech-oss/jwt-go"
 	"net/url"
 	"testing"
 	"time"