added tests for parser. fixed parser when using restricted method list

This commit is contained in:
Dave Grijalva 2015-11-02 15:22:08 -08:00
parent 7ac27fb6ac
commit 774f319043
2 changed files with 61 additions and 19 deletions

View File

@ -32,21 +32,6 @@ func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed} return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed}
} }
// 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 {
return nil, &ValidationError{err: fmt.Sprintf("signing method %v is invalid", alg), Errors: ValidationErrorSignatureInvalid}
}
}
// parse Claims // parse Claims
var claimBytes []byte var claimBytes []byte
if claimBytes, err = DecodeSegment(parts[1]); err != nil { if claimBytes, err = DecodeSegment(parts[1]); err != nil {
@ -69,6 +54,22 @@ func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
return token, &ValidationError{err: "signing method (alg) is unspecified.", Errors: ValidationErrorUnverifiable} return token, &ValidationError{err: "signing method (alg) is unspecified.", Errors: ValidationErrorUnverifiable}
} }
// 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, &ValidationError{err: fmt.Sprintf("signing method %v is invalid", alg), Errors: ValidationErrorSignatureInvalid}
}
}
// Lookup key // Lookup key
var key interface{} var key interface{}
if keyFunc == nil { if keyFunc == nil {

View File

@ -1,6 +1,7 @@
package jwt_test package jwt_test
import ( import (
"encoding/json"
"fmt" "fmt"
"github.com/dgrijalva/jwt-go" "github.com/dgrijalva/jwt-go"
"io/ioutil" "io/ioutil"
@ -25,6 +26,7 @@ var jwtTestData = []struct {
claims map[string]interface{} claims map[string]interface{}
valid bool valid bool
errors uint32 errors uint32
parser *jwt.Parser
}{ }{
{ {
"basic", "basic",
@ -33,6 +35,7 @@ var jwtTestData = []struct {
map[string]interface{}{"foo": "bar"}, map[string]interface{}{"foo": "bar"},
true, true,
0, 0,
nil,
}, },
{ {
"basic expired", "basic expired",
@ -41,6 +44,7 @@ var jwtTestData = []struct {
map[string]interface{}{"foo": "bar", "exp": float64(time.Now().Unix() - 100)}, map[string]interface{}{"foo": "bar", "exp": float64(time.Now().Unix() - 100)},
false, false,
jwt.ValidationErrorExpired, jwt.ValidationErrorExpired,
nil,
}, },
{ {
"basic nbf", "basic nbf",
@ -49,6 +53,7 @@ var jwtTestData = []struct {
map[string]interface{}{"foo": "bar", "nbf": float64(time.Now().Unix() + 100)}, map[string]interface{}{"foo": "bar", "nbf": float64(time.Now().Unix() + 100)},
false, false,
jwt.ValidationErrorNotValidYet, jwt.ValidationErrorNotValidYet,
nil,
}, },
{ {
"expired and nbf", "expired and nbf",
@ -57,6 +62,7 @@ var jwtTestData = []struct {
map[string]interface{}{"foo": "bar", "nbf": float64(time.Now().Unix() + 100), "exp": float64(time.Now().Unix() - 100)}, map[string]interface{}{"foo": "bar", "nbf": float64(time.Now().Unix() + 100), "exp": float64(time.Now().Unix() - 100)},
false, false,
jwt.ValidationErrorNotValidYet | jwt.ValidationErrorExpired, jwt.ValidationErrorNotValidYet | jwt.ValidationErrorExpired,
nil,
}, },
{ {
"basic invalid", "basic invalid",
@ -65,6 +71,7 @@ var jwtTestData = []struct {
map[string]interface{}{"foo": "bar"}, map[string]interface{}{"foo": "bar"},
false, false,
jwt.ValidationErrorSignatureInvalid, jwt.ValidationErrorSignatureInvalid,
nil,
}, },
{ {
"basic nokeyfunc", "basic nokeyfunc",
@ -73,6 +80,7 @@ var jwtTestData = []struct {
map[string]interface{}{"foo": "bar"}, map[string]interface{}{"foo": "bar"},
false, false,
jwt.ValidationErrorUnverifiable, jwt.ValidationErrorUnverifiable,
nil,
}, },
{ {
"basic nokey", "basic nokey",
@ -81,6 +89,7 @@ var jwtTestData = []struct {
map[string]interface{}{"foo": "bar"}, map[string]interface{}{"foo": "bar"},
false, false,
jwt.ValidationErrorSignatureInvalid, jwt.ValidationErrorSignatureInvalid,
nil,
}, },
{ {
"basic errorkey", "basic errorkey",
@ -89,6 +98,25 @@ var jwtTestData = []struct {
map[string]interface{}{"foo": "bar"}, map[string]interface{}{"foo": "bar"},
false, false,
jwt.ValidationErrorUnverifiable, jwt.ValidationErrorUnverifiable,
nil,
},
{
"invalid signing method",
"",
defaultKeyFunc,
map[string]interface{}{"foo": "bar"},
false,
jwt.ValidationErrorSignatureInvalid,
&jwt.Parser{ValidMethods: []string{"HS256"}},
},
{
"JSON Number",
"",
defaultKeyFunc,
map[string]interface{}{"foo": json.Number("123.4")},
true,
0,
&jwt.Parser{UseJSONNumber: true},
}, },
} }
@ -116,12 +144,19 @@ func makeSample(c map[string]interface{}) string {
return s return s
} }
func TestJWT(t *testing.T) { func TestParser_Parse(t *testing.T) {
for _, data := range jwtTestData { for _, data := range jwtTestData {
if data.tokenString == "" { if data.tokenString == "" {
data.tokenString = makeSample(data.claims) data.tokenString = makeSample(data.claims)
} }
token, err := jwt.Parse(data.tokenString, data.keyfunc)
var token *jwt.Token
var err error
if data.parser != nil {
token, err = data.parser.Parse(data.tokenString, data.keyfunc)
} else {
token, err = jwt.Parse(data.tokenString, data.keyfunc)
}
if !reflect.DeepEqual(data.claims, token.Claims) { if !reflect.DeepEqual(data.claims, token.Claims) {
t.Errorf("[%v] Claims mismatch. Expecting: %v Got: %v", data.name, data.claims, token.Claims) t.Errorf("[%v] Claims mismatch. Expecting: %v Got: %v", data.name, data.claims, token.Claims)
@ -137,8 +172,8 @@ func TestJWT(t *testing.T) {
t.Errorf("[%v] Expecting error. Didn't get one.", data.name) t.Errorf("[%v] Expecting error. Didn't get one.", data.name)
} else { } else {
// compare the bitfield part of the error // compare the bitfield part of the error
if err.(*jwt.ValidationError).Errors != data.errors { if e := err.(*jwt.ValidationError).Errors; e != data.errors {
t.Errorf("[%v] Errors don't match expectation", data.name) t.Errorf("[%v] Errors don't match expectation. %v != %v", data.name, e, data.errors)
} }
} }
@ -149,6 +184,12 @@ func TestJWT(t *testing.T) {
func TestParseRequest(t *testing.T) { func TestParseRequest(t *testing.T) {
// Bearer token request // Bearer token request
for _, data := range jwtTestData { for _, data := range jwtTestData {
// FIXME: custom parsers are not supported by this helper. skip tests that require them
if data.parser != nil {
t.Logf("Skipping [%v]. Custom parsers are not supported by ParseRequest", data.name)
continue
}
if data.tokenString == "" { if data.tokenString == "" {
data.tokenString = makeSample(data.claims) data.tokenString = makeSample(data.claims)
} }