Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
added support for none, hopefully in a way you can't use accidentally
- Loading branch information
There are no files selected for viewing
| @@ -0,0 +1,54 @@ | ||
| package jwt | ||
|
|
||
| // Implements the none signing method. This is required by the spec | ||
| // but you probably should never use it. | ||
| var SigningMethodNone *signingMethodNone | ||
|
|
||
| const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed" | ||
|
|
||
| var NoneSignatureTypeDisallowedError error | ||
|
|
||
| type signingMethodNone struct{} | ||
| type unsafeNoneMagicConstant string | ||
|
|
||
| func init() { | ||
| SigningMethodNone = &signingMethodNone{} | ||
| NoneSignatureTypeDisallowedError = &ValidationError{ | ||
| "'none' signature type is not allowed", | ||
| ValidationErrorSignatureInvalid, | ||
| } | ||
| RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod { | ||
| return SigningMethodNone | ||
| }) | ||
| } | ||
|
|
||
| func (m *signingMethodNone) Alg() string { | ||
| return "none" | ||
| } | ||
|
|
||
| // Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key | ||
| func (m *signingMethodNone) Verify(signingString, signature string, key interface{}) (err error) { | ||
| // Key must be UnsafeAllowNoneSignatureType to prevent accidentally | ||
| // accepting 'none' signing method | ||
| if _, ok := key.(unsafeNoneMagicConstant); !ok { | ||
| return NoneSignatureTypeDisallowedError | ||
| } | ||
| // If signing method is none, signature must be an empty string | ||
| if signature != "" { | ||
| return &ValidationError{ | ||
| "'none' signing method with non-empty signature", | ||
| ValidationErrorSignatureInvalid, | ||
| } | ||
| } | ||
|
|
||
| // Accept 'none' signing method. | ||
| return nil | ||
| } | ||
|
|
||
| // Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key | ||
| func (m *signingMethodNone) Sign(signingString string, key interface{}) (string, error) { | ||
| if _, ok := key.(unsafeNoneMagicConstant); ok { | ||
| return "", nil | ||
| } | ||
| return "", NoneSignatureTypeDisallowedError | ||
| } |
| @@ -0,0 +1,72 @@ | ||
| package jwt_test | ||
|
|
||
| import ( | ||
| "github.com/dgrijalva/jwt-go" | ||
| "strings" | ||
| "testing" | ||
| ) | ||
|
|
||
| var noneTestData = []struct { | ||
| name string | ||
| tokenString string | ||
| alg string | ||
| key interface{} | ||
| claims map[string]interface{} | ||
| valid bool | ||
| }{ | ||
| { | ||
| "Basic", | ||
| "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.", | ||
| "none", | ||
| jwt.UnsafeAllowNoneSignatureType, | ||
| map[string]interface{}{"foo": "bar"}, | ||
| true, | ||
| }, | ||
| { | ||
| "Basic - no key", | ||
| "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.", | ||
| "none", | ||
| nil, | ||
| map[string]interface{}{"foo": "bar"}, | ||
| false, | ||
| }, | ||
| { | ||
| "Signed", | ||
| "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.W-jEzRfBigtCWsinvVVuldiuilzVdU5ty0MvpLaSaqK9PlAWWlDQ1VIQ_qSKzwL5IXaZkvZFJXT3yL3n7OUVu7zCNJzdwznbC8Z-b0z2lYvcklJYi2VOFRcGbJtXUqgjk2oGsiqUMUMOLP70TTefkpsgqDxbRh9CDUfpOJgW-dU7cmgaoswe3wjUAUi6B6G2YEaiuXC0XScQYSYVKIzgKXJV8Zw-7AN_DBUI4GkTpsvQ9fVVjZM9csQiEXhYekyrKu1nu_POpQonGd8yqkIyXPECNmmqH5jH4sFiF67XhD7_JpkvLziBpI-uh86evBUadmHhb9Otqw3uV3NTaXLzJw", | ||
| "none", | ||
| jwt.UnsafeAllowNoneSignatureType, | ||
| map[string]interface{}{"foo": "bar"}, | ||
| false, | ||
| }, | ||
| } | ||
|
|
||
| func TestNoneVerify(t *testing.T) { | ||
| for _, data := range noneTestData { | ||
| parts := strings.Split(data.tokenString, ".") | ||
|
|
||
| method := jwt.GetSigningMethod(data.alg) | ||
| err := method.Verify(strings.Join(parts[0:2], "."), parts[2], data.key) | ||
| if data.valid && err != nil { | ||
| t.Errorf("[%v] Error while verifying key: %v", data.name, err) | ||
| } | ||
| if !data.valid && err == nil { | ||
| t.Errorf("[%v] Invalid key passed validation", data.name) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func TestNoneSign(t *testing.T) { | ||
| for _, data := range noneTestData { | ||
| if data.valid { | ||
| parts := strings.Split(data.tokenString, ".") | ||
| method := jwt.GetSigningMethod(data.alg) | ||
| sig, err := method.Sign(strings.Join(parts[0:2], "."), data.key) | ||
| if err != nil { | ||
| t.Errorf("[%v] Error signing token: %v", data.name, err) | ||
| } | ||
| if sig != parts[2] { | ||
| t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", data.name, sig, parts[2]) | ||
| } | ||
| } | ||
| } | ||
| } |

