forked from golang-jwt/jwt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into release_3_0_0
- Loading branch information
Showing
11 changed files
with
281 additions
and
138 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,5 @@ language: go | |
go: | ||
- 1.3.3 | ||
- 1.4.2 | ||
- 1.5 | ||
- tip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
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 | ||
} | ||
|
||
// 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, keyFunc, &MapClaims{}) | ||
} | ||
|
||
func (p *Parser) ParseWithClaims(tokenString string, keyFunc Keyfunc, claims Claims) (*Token, error) { | ||
parts := strings.Split(tokenString, ".") | ||
if len(parts) != 3 { | ||
return nil, &ValidationError{err: "token contains an invalid number of segments", Errors: ValidationErrorMalformed} | ||
} | ||
|
||
var err error | ||
token := &Token{Raw: tokenString} | ||
|
||
// parse Header | ||
var headerBytes []byte | ||
if headerBytes, err = DecodeSegment(parts[0]); err != nil { | ||
return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed} | ||
} | ||
if err = json.Unmarshal(headerBytes, &token.Header); err != nil { | ||
return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed} | ||
} | ||
|
||
// parse Claims | ||
var claimBytes []byte | ||
|
||
if claimBytes, err = DecodeSegment(parts[1]); err != nil { | ||
return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed} | ||
} | ||
dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) | ||
if p.UseJSONNumber { | ||
dec.UseNumber() | ||
} | ||
if err = dec.Decode(&claims); err != nil { | ||
return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed} | ||
} | ||
|
||
token.Claims = claims | ||
|
||
// Lookup signature method | ||
if method, ok := token.Header["alg"].(string); ok { | ||
if token.Method = GetSigningMethod(method); token.Method == nil { | ||
return token, &ValidationError{err: "signing method (alg) is unavailable.", Errors: ValidationErrorUnverifiable} | ||
} | ||
} else { | ||
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 | ||
var key interface{} | ||
if keyFunc == nil { | ||
// keyFunc was not provided. short circuiting validation | ||
return token, &ValidationError{err: "no Keyfunc was provided.", Errors: ValidationErrorUnverifiable} | ||
} | ||
if key, err = keyFunc(token); err != nil { | ||
// keyFunc returned an error | ||
return token, &ValidationError{err: err.Error(), Errors: ValidationErrorUnverifiable} | ||
} | ||
|
||
vErr := &ValidationError{} | ||
|
||
// Validate Claims | ||
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{err: err.Error(), Errors: ValidationErrorClaimsInvalid} | ||
} else { | ||
vErr = e | ||
} | ||
} | ||
|
||
// Perform validation | ||
if err = token.Method.Verify(strings.Join(parts[0:2], "."), parts[2], key); err != nil { | ||
vErr.err = err.Error() | ||
vErr.Errors |= ValidationErrorSignatureInvalid | ||
} | ||
|
||
if vErr.valid() { | ||
token.Valid = true | ||
return token, nil | ||
} | ||
|
||
return token, vErr | ||
} |
Oops, something went wrong.