diff --git a/claims.go b/claims.go index be1e79a..ef4e57b 100644 --- a/claims.go +++ b/claims.go @@ -1,6 +1,9 @@ package jwt -import "crypto/subtle" +import ( + "crypto/subtle" + "encoding/json" +) // 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 @@ -94,15 +97,27 @@ func (m MapClaims) VerifyAudience(cmp string, req bool) bool { // 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 { - exp, _ := m["exp"].(float64) - return verifyExp(int64(exp), cmp, req) + 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 { - iat, _ := m["iat"].(float64) - return verifyIat(int64(iat), cmp, req) + 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. @@ -115,8 +130,14 @@ func (m MapClaims) VerifyIssuer(cmp string, req bool) bool { // 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 { - nbf, _ := m["nbf"].(float64) - return verifyNbf(int64(nbf), cmp, req) + 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". diff --git a/parser_test.go b/parser_test.go index 8448986..3736b09 100644 --- a/parser_test.go +++ b/parser_test.go @@ -143,6 +143,33 @@ var jwtTestData = []struct { 0, &jwt.Parser{UseJSONNumber: true}, }, + { + "JSON Number - basic expired", + "", // autogen + defaultKeyFunc, + jwt.MapClaims{"foo": "bar", "exp": json.Number(fmt.Sprintf("%v", time.Now().Unix()-100))}, + false, + jwt.ValidationErrorExpired, + &jwt.Parser{UseJSONNumber: true}, + }, + { + "JSON Number - basic nbf", + "", // autogen + defaultKeyFunc, + jwt.MapClaims{"foo": "bar", "nbf": json.Number(fmt.Sprintf("%v", time.Now().Unix()+100))}, + false, + jwt.ValidationErrorNotValidYet, + &jwt.Parser{UseJSONNumber: true}, + }, + { + "JSON Number - expired and nbf", + "", // autogen + defaultKeyFunc, + jwt.MapClaims{"foo": "bar", "nbf": json.Number(fmt.Sprintf("%v", time.Now().Unix()+100)), "exp": json.Number(fmt.Sprintf("%v", time.Now().Unix()-100))}, + false, + jwt.ValidationErrorNotValidYet | jwt.ValidationErrorExpired, + &jwt.Parser{UseJSONNumber: true}, + }, } func TestParser_Parse(t *testing.T) {