Repository: snowflakedb/gosnowflake
Pull request #350 (2020-11-17 01:12:42)

SNOW-224618 Update JWT Dependency
### Description
Update JWT dependency

### 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


sfc-gh-hchaturvedi: @sfc-gh-jbahk what are these deleted files? 
sfc-gh-jbahk: @sfc-gh-hchaturvedi They are the external deps, and yes we include the entire repo for external deps.

Patch:
diff --git a/auth.go b/auth.go
index 58a2293..1ebfda6 100644
--- a/auth.go
+++ b/auth.go
@@ -14,7 +14,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/dgrijalva/jwt-go"
+	"github.com/dgrijalva/jwt-go/v4"
 	"github.com/google/uuid"
 
 	"crypto/sha256"
diff --git a/go.mod b/go.mod
index 7e49553..0d0f046 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 v3.2.0+incompatible
+	github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1
 	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 3760b96..9cd6469 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 v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
-github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+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/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/.travis.yml b/vendor/github.com/dgrijalva/jwt-go/.travis.yml
deleted file mode 100644
index 1027f56..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/.travis.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-language: go
-
-script:
-    - go vet ./...
-    - go test -v ./...
-
-go:
-  - 1.3
-  - 1.4
-  - 1.5
-  - 1.6
-  - 1.7
-  - tip
diff --git a/vendor/github.com/dgrijalva/jwt-go/claims.go b/vendor/github.com/dgrijalva/jwt-go/claims.go
deleted file mode 100644
index f0228f0..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/claims.go
+++ /dev/null
@@ -1,134 +0,0 @@
-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 aud == "" {
-		return !required
-	}
-	if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 {
-		return true
-	} else {
-		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/ecdsa.go b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go
deleted file mode 100644
index f977381..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/ecdsa.go
+++ /dev/null
@@ -1,148 +0,0 @@
-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/errors.go b/vendor/github.com/dgrijalva/jwt-go/errors.go
deleted file mode 100644
index 1c93024..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/errors.go
+++ /dev/null
@@ -1,59 +0,0 @@
-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/map_claims.go b/vendor/github.com/dgrijalva/jwt-go/map_claims.go
deleted file mode 100644
index 291213c..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/map_claims.go
+++ /dev/null
@@ -1,94 +0,0 @@
-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, _ := m["aud"].(string)
-	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/parser.go b/vendor/github.com/dgrijalva/jwt-go/parser.go
deleted file mode 100644
index d6901d9..0000000
--- a/vendor/github.com/dgrijalva/jwt-go/parser.go
+++ /dev/null
@@ -1,148 +0,0 @@
-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/.gitignore b/vendor/github.com/dgrijalva/jwt-go/v4/.gitignore
similarity index 100%
rename from vendor/github.com/dgrijalva/jwt-go/.gitignore
rename to vendor/github.com/dgrijalva/jwt-go/v4/.gitignore
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/.travis.yml b/vendor/github.com/dgrijalva/jwt-go/v4/.travis.yml
new file mode 100644
index 0000000..ade3c58
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/.travis.yml
@@ -0,0 +1,11 @@
+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/LICENSE b/vendor/github.com/dgrijalva/jwt-go/v4/LICENSE
similarity index 100%
rename from vendor/github.com/dgrijalva/jwt-go/LICENSE
rename to vendor/github.com/dgrijalva/jwt-go/v4/LICENSE
diff --git a/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md b/vendor/github.com/dgrijalva/jwt-go/v4/MIGRATION_GUIDE.md
similarity index 97%
rename from vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md
rename to vendor/github.com/dgrijalva/jwt-go/v4/MIGRATION_GUIDE.md
index 7fc1f79..343afd8 100644
--- a/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/MIGRATION_GUIDE.md
@@ -1,3 +1,7 @@
+## 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.
@@ -82,7 +86,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/README.md b/vendor/github.com/dgrijalva/jwt-go/v4/README.md
similarity index 54%
rename from vendor/github.com/dgrijalva/jwt-go/README.md
rename to vendor/github.com/dgrijalva/jwt-go/v4/README.md
index d358d88..230589b 100644
--- a/vendor/github.com/dgrijalva/jwt-go/README.md
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/README.md
@@ -5,56 +5,57 @@
 
 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 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. 
+**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.
 
 **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/2015/03/31/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-jones-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 the Google App Engine signing tools: https://github.com/someone1/gcp-jwt-go
+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
 
 ## Compliance
 
 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).
 
-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.
+As of version 4, this project is compatible with go modules. You should use that to ensure you have no unpleasant surprises when updating.
 
-**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.
+**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.
 
 ## Usage Tips
 
@@ -62,14 +63,14 @@ While we try to make it obvious when we make breaking changes, there isn't a gre
 
 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.
 
@@ -79,9 +80,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
 
@@ -89,9 +90,9 @@ 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.
 
 ## More
 
diff --git a/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md b/vendor/github.com/dgrijalva/jwt-go/v4/VERSION_HISTORY.md
similarity index 69%
rename from vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md
rename to vendor/github.com/dgrijalva/jwt-go/v4/VERSION_HISTORY.md
index 6370298..fffaa37 100644
--- a/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/VERSION_HISTORY.md
@@ -1,5 +1,28 @@
 ## `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/dgrijalva/jwt-go/v4/claim_strings.go b/vendor/github.com/dgrijalva/jwt-go/v4/claim_strings.go
new file mode 100644
index 0000000..057b684
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/claim_strings.go
@@ -0,0 +1,47 @@
+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
new file mode 100644
index 0000000..a065328
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/claims.go
@@ -0,0 +1,64 @@
+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/doc.go b/vendor/github.com/dgrijalva/jwt-go/v4/doc.go
similarity index 100%
rename from vendor/github.com/dgrijalva/jwt-go/doc.go
rename to vendor/github.com/dgrijalva/jwt-go/v4/doc.go
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/ecdsa.go b/vendor/github.com/dgrijalva/jwt-go/v4/ecdsa.go
new file mode 100644
index 0000000..9a0d608
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/ecdsa.go
@@ -0,0 +1,173 @@
+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/ecdsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/v4/ecdsa_utils.go
similarity index 76%
rename from vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go
rename to vendor/github.com/dgrijalva/jwt-go/v4/ecdsa_utils.go
index d19624b..627e7db 100644
--- a/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/ecdsa_utils.go
@@ -7,12 +7,14 @@ 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")
 )
 
-// Parse PEM encoded Elliptic Curve Private Key Structure
+// ParseECPrivateKeyFromPEM is a helper function for
+// parsing a PEM encoded Elliptic Curve Private Key Structure
 func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
 	var err error
 
@@ -37,7 +39,8 @@ func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
 	return pkey, nil
 }
 
-// Parse PEM encoded PKCS1 or PKCS8 public key
+// ParseECPublicKeyFromPEM is a helper function for
+// parsing a PEM encoded PKCS1 or PKCS8 public key
 func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
 	var err error
 
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/errors.go b/vendor/github.com/dgrijalva/jwt-go/v4/errors.go
new file mode 100644
index 0000000..d7a53ba
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/errors.go
@@ -0,0 +1,204 @@
+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
new file mode 100644
index 0000000..284213d
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/go.mod
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 0000000..3ab73ea
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/go.sum
@@ -0,0 +1,2 @@
+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/hmac.go b/vendor/github.com/dgrijalva/jwt-go/v4/hmac.go
similarity index 80%
rename from vendor/github.com/dgrijalva/jwt-go/hmac.go
rename to vendor/github.com/dgrijalva/jwt-go/v4/hmac.go
index addbe5d..2c91012 100644
--- a/vendor/github.com/dgrijalva/jwt-go/hmac.go
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/hmac.go
@@ -6,7 +6,7 @@ import (
 	"errors"
 )
 
-// Implements the HMAC-SHA family of signing methods signing methods
+// SigningMethodHMAC implements the HMAC-SHA family of signing methods
 // Expects key type of []byte for both signing and validation
 type SigningMethodHMAC struct {
 	Name string
@@ -41,6 +41,7 @@ func init() {
 	})
 }
 
+// Alg implements SigningMethod
 func (m *SigningMethodHMAC) Alg() string {
 	return m.Name
 }
@@ -50,7 +51,7 @@ func (m *SigningMethodHMAC) Verify(signingString, signature string, key interfac
 	// Verify the key is the right type
 	keyBytes, ok := key.([]byte)
 	if !ok {
-		return ErrInvalidKeyType
+		return NewInvalidKeyTypeError("[]byte", key)
 	}
 
 	// Decode signature, for comparison
@@ -77,19 +78,20 @@ func (m *SigningMethodHMAC) Verify(signingString, signature string, key interfac
 	return nil
 }
 
-// Implements the Sign method from SigningMethod for this signing method.
+// Sign implements the Sign method from SigningMethod
 // Key must be []byte
 func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) {
-	if keyBytes, ok := key.([]byte); ok {
-		if !m.Hash.Available() {
-			return "", ErrHashUnavailable
-		}
-
-		hasher := hmac.New(m.Hash.New, keyBytes)
-		hasher.Write([]byte(signingString))
+	keyBytes, ok := key.([]byte)
+	if !ok {
+		return "", NewInvalidKeyTypeError("[]byte", key)
+	}
 
-		return EncodeSegment(hasher.Sum(nil)), nil
+	if !m.Hash.Available() {
+		return "", ErrHashUnavailable
 	}
 
-	return "", ErrInvalidKeyType
+	hasher := hmac.New(m.Hash.New, keyBytes)
+	hasher.Write([]byte(signingString))
+
+	return EncodeSegment(hasher.Sum(nil)), nil
 }
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/keyfunc.go b/vendor/github.com/dgrijalva/jwt-go/v4/keyfunc.go
new file mode 100644
index 0000000..2f15a8f
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/keyfunc.go
@@ -0,0 +1,21 @@
+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
new file mode 100644
index 0000000..d721c33
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/map_claims.go
@@ -0,0 +1,83 @@
+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/none.go b/vendor/github.com/dgrijalva/jwt-go/v4/none.go
similarity index 67%
rename from vendor/github.com/dgrijalva/jwt-go/none.go
rename to vendor/github.com/dgrijalva/jwt-go/v4/none.go
index f04d189..a5caed3 100644
--- a/vendor/github.com/dgrijalva/jwt-go/none.go
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/none.go
@@ -1,11 +1,16 @@
 package jwt
 
-// Implements the none signing method.  This is required by the spec
+// SigningMethodNone 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{}
@@ -13,7 +18,7 @@ type unsafeNoneMagicConstant string
 
 func init() {
 	SigningMethodNone = &signingMethodNone{}
-	NoneSignatureTypeDisallowedError = NewValidationError("'none' signature type is not allowed", ValidationErrorSignatureInvalid)
+	NoneSignatureTypeDisallowedError = &InvalidSignatureError{Message: "'none' signature type is not allowed"}
 
 	RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod {
 		return SigningMethodNone
@@ -33,10 +38,7 @@ func (m *signingMethodNone) Verify(signingString, signature string, key interfac
 	}
 	// If signing method is none, signature must be an empty string
 	if signature != "" {
-		return NewValidationError(
-			"'none' signing method with non-empty signature",
-			ValidationErrorSignatureInvalid,
-		)
+		return &InvalidSignatureError{Message: "'none' signing method with non-empty signature"}
 	}
 
 	// Accept 'none' signing method.
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/parser.go b/vendor/github.com/dgrijalva/jwt-go/v4/parser.go
new file mode 100644
index 0000000..1f1a9c0
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/parser.go
@@ -0,0 +1,168 @@
+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
new file mode 100644
index 0000000..fd285eb
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/parser_option.go
@@ -0,0 +1,74 @@
+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/rsa.go b/vendor/github.com/dgrijalva/jwt-go/v4/rsa.go
similarity index 64%
rename from vendor/github.com/dgrijalva/jwt-go/rsa.go
rename to vendor/github.com/dgrijalva/jwt-go/v4/rsa.go
index e4caf1c..72ba2d6 100644
--- a/vendor/github.com/dgrijalva/jwt-go/rsa.go
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/rsa.go
@@ -4,9 +4,10 @@ import (
 	"crypto"
 	"crypto/rand"
 	"crypto/rsa"
+	"fmt"
 )
 
-// Implements the RSA family of signing methods signing methods
+// SigningMethodRSA implements the RSA family of signing methods signing methods
 // Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation
 type SigningMethodRSA struct {
 	Name string
@@ -40,11 +41,12 @@ func init() {
 	})
 }
 
+// Alg implements the Alg method from SigningMethod
 func (m *SigningMethodRSA) Alg() string {
 	return m.Name
 }
 
-// Implements the Verify method from SigningMethod
+// Verify 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
@@ -58,8 +60,16 @@ func (m *SigningMethodRSA) Verify(signingString, signature string, key interface
 	var rsaKey *rsa.PublicKey
 	var ok bool
 
-	if rsaKey, ok = key.(*rsa.PublicKey); !ok {
-		return ErrInvalidKeyType
+	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)
 	}
 
 	// Create hasher
@@ -73,15 +83,19 @@ func (m *SigningMethodRSA) Verify(signingString, signature string, key interface
 	return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig)
 }
 
-// Implements the Sign method from SigningMethod
+// Sign 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 rsaKey *rsa.PrivateKey
+	var signer crypto.Signer
 	var ok bool
 
-	// Validate type of key
-	if rsaKey, ok = key.(*rsa.PrivateKey); !ok {
-		return "", ErrInvalidKey
+	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)}
 	}
 
 	// Create the hasher
@@ -93,9 +107,9 @@ func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string,
 	hasher.Write([]byte(signingString))
 
 	// Sign the string and return the encoded bytes
-	if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil {
-		return EncodeSegment(sigBytes), nil
-	} else {
+	sigBytes, err := signer.Sign(rand.Reader, hasher.Sum(nil), m.Hash)
+	if err != nil {
 		return "", err
 	}
+	return EncodeSegment(sigBytes), nil
 }
diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go b/vendor/github.com/dgrijalva/jwt-go/v4/rsa_pss.go
similarity index 70%
rename from vendor/github.com/dgrijalva/jwt-go/rsa_pss.go
rename to vendor/github.com/dgrijalva/jwt-go/v4/rsa_pss.go
index 10ee9db..aa3ba39 100644
--- a/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/rsa_pss.go
@@ -6,9 +6,10 @@ import (
 	"crypto"
 	"crypto/rand"
 	"crypto/rsa"
+	"fmt"
 )
 
-// Implements the RSAPSS family of signing methods signing methods
+// SigningMethodRSAPSS implements the RSAPSS family of signing methods
 type SigningMethodRSAPSS struct {
 	*SigningMethodRSA
 	Options *rsa.PSSOptions
@@ -68,7 +69,7 @@ func init() {
 	})
 }
 
-// Implements the Verify method from SigningMethod
+// Verify 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
@@ -80,11 +81,18 @@ 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 ErrInvalidKey
+		return NewInvalidKeyTypeError("*rsa.PublicKey or crypto.Signer", key)
 	}
 
 	// Create hasher
@@ -97,16 +105,19 @@ func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interf
 	return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, m.Options)
 }
 
-// Implements the Sign method from SigningMethod
+// Sign 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 rsaKey *rsa.PrivateKey
+	var signer crypto.Signer
+	var ok bool
 
-	switch k := key.(type) {
-	case *rsa.PrivateKey:
-		rsaKey = k
-	default:
-		return "", ErrInvalidKeyType
+	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)}
 	}
 
 	// Create the hasher
@@ -118,9 +129,10 @@ func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) (strin
 	hasher.Write([]byte(signingString))
 
 	// Sign the string and return the encoded bytes
-	if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil {
-		return EncodeSegment(sigBytes), nil
-	} else {
+	sigBytes, err := signer.Sign(rand.Reader, hasher.Sum(nil), m.Options)
+	if err != nil {
 		return "", err
 	}
+	return EncodeSegment(sigBytes), nil
+
 }
diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/v4/rsa_utils.go
similarity index 77%
rename from vendor/github.com/dgrijalva/jwt-go/rsa_utils.go
rename to vendor/github.com/dgrijalva/jwt-go/v4/rsa_utils.go
index a5ababf..b0dae4b 100644
--- a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/rsa_utils.go
@@ -7,13 +7,15 @@ 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 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")
 )
 
-// Parse PEM encoded PKCS1 or PKCS8 private key
+// ParseRSAPrivateKeyFromPEM is a helper method for
+// parsing PEM encoded PKCS1 or PKCS8 private key
 func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
 	var err error
 
@@ -39,7 +41,8 @@ func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
 	return pkey, nil
 }
 
-// Parse PEM encoded PKCS1 or PKCS8 private key protected with password
+// ParseRSAPrivateKeyFromPEMWithPassword is a helper method for
+// parsing PEM encoded PKCS1 or PKCS8 private key, encrypted with a password
 func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) {
 	var err error
 
@@ -71,7 +74,8 @@ func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.Pr
 	return pkey, nil
 }
 
-// Parse PEM encoded PKCS1 or PKCS8 public key
+// ParseRSAPublicKeyFromPEM is a helper method for
+// parsing a 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/signing_method.go b/vendor/github.com/dgrijalva/jwt-go/v4/signing_method.go
similarity index 71%
rename from vendor/github.com/dgrijalva/jwt-go/signing_method.go
rename to vendor/github.com/dgrijalva/jwt-go/v4/signing_method.go
index ed1f212..5e50243 100644
--- a/vendor/github.com/dgrijalva/jwt-go/signing_method.go
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/signing_method.go
@@ -7,14 +7,15 @@ import (
 var signingMethods = map[string]func() SigningMethod{}
 var signingMethodLock = new(sync.RWMutex)
 
-// Implement SigningMethod to add new methods for signing or verifying tokens.
+// SigningMethod is the interface used for signing and 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')
 }
 
-// Register the "alg" name and a factory function for signing method.
+// RegisterSigningMethod stores the "alg" name and a factory function pair
+// used internally for looking up a signing method based on "alg".
 // This is typically done during init() in the method's implementation
 func RegisterSigningMethod(alg string, f func() SigningMethod) {
 	signingMethodLock.Lock()
@@ -23,7 +24,8 @@ func RegisterSigningMethod(alg string, f func() SigningMethod) {
 	signingMethods[alg] = f
 }
 
-// Get a signing method from an "alg" string
+// GetSigningMethod returns the signing method registered by RegisterSigningMethod
+// This is used by the library internally during parsing and validation.
 func GetSigningMethod(alg string) (method SigningMethod) {
 	signingMethodLock.RLock()
 	defer signingMethodLock.RUnlock()
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/signing_option.go b/vendor/github.com/dgrijalva/jwt-go/v4/signing_option.go
new file mode 100644
index 0000000..cecead2
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/signing_option.go
@@ -0,0 +1,38 @@
+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
new file mode 100644
index 0000000..aee72ae
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/time.go
@@ -0,0 +1,78 @@
+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/token.go b/vendor/github.com/dgrijalva/jwt-go/v4/token.go
similarity index 50%
rename from vendor/github.com/dgrijalva/jwt-go/token.go
rename to vendor/github.com/dgrijalva/jwt-go/v4/token.go
index d637e08..5ab1eb5 100644
--- a/vendor/github.com/dgrijalva/jwt-go/token.go
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/token.go
@@ -12,13 +12,7 @@ import (
 // server uses a different time zone than your tokens.
 var TimeFunc = time.Now
 
-// 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
+// Token represents 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
@@ -29,11 +23,12 @@ type Token struct {
 	Valid     bool                   // Is the token valid?  Populated when you Parse/Verify a token
 }
 
-// Create a new Token.  Takes a signing method
+// New creates a new Token.  Takes a signing method. Uses the default claims type, MapClaims.
 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{}{
@@ -45,11 +40,11 @@ func NewWithClaims(method SigningMethod, claims Claims) *Token {
 	}
 }
 
-// Get the complete, signed token
-func (t *Token) SignedString(key interface{}) (string, error) {
+// SignedString returns the complete, signed token
+func (t *Token) SignedString(key interface{}, opts ...SigningOption) (string, error) {
 	var sig, sstr string
 	var err error
-	if sstr, err = t.SigningString(); err != nil {
+	if sstr, err = t.SigningString(opts...); err != nil {
 		return "", err
 	}
 	if sig, err = t.Method.Sign(sstr, key); err != nil {
@@ -58,51 +53,58 @@ func (t *Token) SignedString(key interface{}) (string, error) {
 	return strings.Join([]string{sstr, sig}, "."), nil
 }
 
-// Generate the signing string.  This is the
+// SigningString generates 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() (string, error) {
-	var err error
+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}
 	parts := make([]string, 2)
-	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
-			}
+	for i, v := range inputParts {
+		ctx := CodingContext{FieldDescriptor(i), t.Header}
+		jsonValue, err := cfg.marshaller(ctx, v)
+		if err != nil {
+			return "", err
 		}
-
 		parts[i] = EncodeSegment(jsonValue)
 	}
 	return strings.Join(parts, "."), nil
 }
 
-// Parse, validate, and return a token.
+func (t *Token) defaultMarshaller(ctx CodingContext, v interface{}) ([]byte, error) {
+	return json.Marshal(v)
+}
+
+// Parse then 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 Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
-	return new(Parser).Parse(tokenString, keyFunc)
+// Claims type will be the default, MapClaims
+func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) {
+	return NewParser(options...).Parse(tokenString, keyFunc)
 }
 
-func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
-	return new(Parser).ParseWithClaims(tokenString, claims, 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)
 }
 
-// Encode JWT specific base64url encoding with padding stripped
+// EncodeSegment is used internally for JWT specific base64url encoding with padding stripped
 func EncodeSegment(seg []byte) string {
-	return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=")
+	return base64.RawURLEncoding.EncodeToString(seg)
 }
 
-// Decode JWT specific base64url encoding with padding stripped
+// DecodeSegment is used internally for JWT specific base64url encoding with padding stripped
 func DecodeSegment(seg string) ([]byte, error) {
-	if l := len(seg) % 4; l > 0 {
-		seg += strings.Repeat("=", 4-l)
-	}
-
-	return base64.URLEncoding.DecodeString(seg)
+	return base64.RawURLEncoding.DecodeString(seg)
 }
diff --git a/vendor/github.com/dgrijalva/jwt-go/v4/validation_helper.go b/vendor/github.com/dgrijalva/jwt-go/v4/validation_helper.go
new file mode 100644
index 0000000..2edd0a4
--- /dev/null
+++ b/vendor/github.com/dgrijalva/jwt-go/v4/validation_helper.go
@@ -0,0 +1,151 @@
+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/modules.txt b/vendor/modules.txt
index b6e70c8..89efe5c 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 v3.2.0+incompatible
+# github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1
 ## explicit
-github.com/dgrijalva/jwt-go
+github.com/dgrijalva/jwt-go/v4
 # 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 372985e..6bc8b04 100644
--- a/auth_test.go
+++ b/auth_test.go
@@ -9,7 +9,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"github.com/dgrijalva/jwt-go"
+	"github.com/dgrijalva/jwt-go/v4"
 	"net/url"
 	"testing"
 	"time"