mirror of https://github.com/golang-jwt/jwt.git
base64 decoding fixins
This commit is contained in:
parent
50d3e917c8
commit
18108cfd38
24
jwt.go
24
jwt.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A JWT Token
|
// A JWT Token
|
||||||
|
@ -26,7 +27,7 @@ func Parse(tokenString string, keyFunc func(*Token)([]byte, error)) (token *Toke
|
||||||
token = new(Token)
|
token = new(Token)
|
||||||
// parse Header
|
// parse Header
|
||||||
var headerBytes []byte
|
var headerBytes []byte
|
||||||
if headerBytes, err = base64.URLEncoding.DecodeString(parts[0]); err != nil {
|
if headerBytes, err = DecodeSegment(parts[0]); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = json.Unmarshal(headerBytes, &token.Header); err != nil {
|
if err = json.Unmarshal(headerBytes, &token.Header); err != nil {
|
||||||
|
@ -35,7 +36,7 @@ func Parse(tokenString string, keyFunc func(*Token)([]byte, error)) (token *Toke
|
||||||
|
|
||||||
// parse Claims
|
// parse Claims
|
||||||
var claimBytes []byte
|
var claimBytes []byte
|
||||||
if claimBytes, err = base64.URLEncoding.DecodeString(parts[1]); err != nil {
|
if claimBytes, err = DecodeSegment(parts[1]); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = json.Unmarshal(claimBytes, &token.Claims); err != nil {
|
if err = json.Unmarshal(claimBytes, &token.Claims); err != nil {
|
||||||
|
@ -75,3 +76,22 @@ func Parse(tokenString string, keyFunc func(*Token)([]byte, error)) (token *Toke
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func ParseFromRequest(req *http.Request, keyFunc func(*Token)([]byte, error))(token *Token, err error) {
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodeSegment(seg string)([]byte, error) {
|
||||||
|
// len % 4
|
||||||
|
switch len(seg) % 4 {
|
||||||
|
case 2:
|
||||||
|
seg = seg + "=="
|
||||||
|
case 3:
|
||||||
|
seg = seg + "==="
|
||||||
|
}
|
||||||
|
|
||||||
|
return base64.URLEncoding.DecodeString(seg)
|
||||||
|
}
|
46
jwt_test.go
46
jwt_test.go
|
@ -1,9 +1,51 @@
|
||||||
package jwt
|
package jwt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"io"
|
||||||
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestJWT(t *testing.T) {
|
var jwtTestData = []struct{
|
||||||
|
name string
|
||||||
|
tokenString string
|
||||||
|
claims map[string]interface{}
|
||||||
|
valid bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"basic: foo => bar",
|
||||||
|
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
||||||
|
map[string]interface{}{"foo": "bar"},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"basic invalid: foo => bar",
|
||||||
|
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
||||||
|
map[string]interface{}{"foo": "bar"},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJWT(t *testing.T) {
|
||||||
|
file, _ := os.Open("test/sample_key.pub")
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
io.Copy(buf, file)
|
||||||
|
key := buf.Bytes()
|
||||||
|
file.Close()
|
||||||
|
|
||||||
|
for _, data := range jwtTestData {
|
||||||
|
token, err := Parse(data.tokenString, func(t *Token)([]byte, error){ return key, nil })
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(data.claims, token.Claims) {
|
||||||
|
t.Errorf("[%v] Claims mismatch. Expecting: %v Got: %v", data.name, data.claims, token.Claims)
|
||||||
|
}
|
||||||
|
if data.valid && err != nil {
|
||||||
|
t.Errorf("[%v] Error while verifying token: %v", data.name, err)
|
||||||
|
}
|
||||||
|
if !data.valid && err == nil {
|
||||||
|
t.Errorf("[%v] Invalid token passed validation", data.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
13
rs256.go
13
rs256.go
|
@ -2,7 +2,6 @@ package jwt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"encoding/base64"
|
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
@ -19,17 +18,9 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SigningMethodRS256) Verify(signingString, signature string, key []byte)(err error) {
|
func (m *SigningMethodRS256) Verify(signingString, signature string, key []byte)(err error) {
|
||||||
// len % 4
|
|
||||||
switch len(signature) % 4 {
|
|
||||||
case 2:
|
|
||||||
signature = signature + "=="
|
|
||||||
case 3:
|
|
||||||
signature = signature + "==="
|
|
||||||
}
|
|
||||||
|
|
||||||
// Key
|
// Key
|
||||||
var sig []byte
|
var sig []byte
|
||||||
if sig, err = base64.URLEncoding.DecodeString(signature); err == nil {
|
if sig, err = DecodeSegment(signature); err == nil {
|
||||||
var block *pem.Block
|
var block *pem.Block
|
||||||
if block, _ = pem.Decode(key); block != nil {
|
if block, _ = pem.Decode(key); block != nil {
|
||||||
var parsedKey interface{}
|
var parsedKey interface{}
|
||||||
|
@ -50,6 +41,6 @@ func (m *SigningMethodRS256) Verify(signingString, signature string, key []byte)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SigningMethodRS256) Sign(token, key []byte)error {
|
func (m *SigningMethodRS256) Sign(token *Token, key []byte)error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testData = []struct{
|
var rsaTestData = []struct{
|
||||||
name string
|
name string
|
||||||
tokenString string
|
tokenString string
|
||||||
claims map[string]interface{}
|
claims map[string]interface{}
|
||||||
|
@ -35,7 +35,7 @@ func TestRS256Verify(t *testing.T) {
|
||||||
key := buf.Bytes()
|
key := buf.Bytes()
|
||||||
file.Close()
|
file.Close()
|
||||||
|
|
||||||
for _, data := range testData {
|
for _, data := range rsaTestData {
|
||||||
parts := strings.Split(data.tokenString, ".")
|
parts := strings.Split(data.tokenString, ".")
|
||||||
|
|
||||||
method, _ := GetSigningMethod("RS256")
|
method, _ := GetSigningMethod("RS256")
|
||||||
|
|
|
@ -10,7 +10,7 @@ var signingMethods = map[string]func() SigningMethod{}
|
||||||
// Signing method
|
// Signing method
|
||||||
type SigningMethod interface {
|
type SigningMethod interface {
|
||||||
Verify(signingString, signature string, key []byte)error
|
Verify(signingString, signature string, key []byte)error
|
||||||
Sign(token, key []byte)error
|
Sign(token *Token, key []byte)error
|
||||||
}
|
}
|
||||||
|
|
||||||
func RegisterSigningMethod(alg string, f func() SigningMethod) {
|
func RegisterSigningMethod(alg string, f func() SigningMethod) {
|
||||||
|
|
Loading…
Reference in New Issue