Skip to content

Commit

Permalink
Switching to utilizing global var
Browse files Browse the repository at this point in the history
  • Loading branch information
ajermaky committed Oct 31, 2021
1 parent d7f2c46 commit 25379bc
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 11 deletions.
93 changes: 83 additions & 10 deletions parser_test.go
Expand Up @@ -57,16 +57,6 @@ var jwtTestData = []struct {
nil,
jwt.SigningMethodRS256,
},
{
"basic with padding",
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJwYWRkZWRiYXIifQ==.20kGGJaYekGTRFf8b0TwhuETcR8lv5z2363X5jf7G1yTWVTwOmte5Ii8L8_OQbYwPoiVHmZY6iJPbt_DhCN42AeFY74BcsUhR-BVrYUVhKK0RppuzEcSlILDNeQsJDLEL035CPm1VO6Jrgk7enQPIctVxUesRgswP71OpGvJxy3j1k_J8p0WzZvRZTe1D_2Misa0UDGwnEIHhmr97fIpMSZjFxlcygQw8QN34IHLHIXMaTY1eiCf4CCr6rOS9wUeu7P3CPkmFq9XhxBT_LLCmIMhHnxP5x27FUJE_JZlfek0MmARcrhpsZS2sFhHAiWrjxjOE27jkDtv1nEwn65wMw==",
defaultKeyFunc,
jwt.MapClaims{"foo": "paddedbar"},
true,
0,
nil,
jwt.SigningMethodRS256,
},
{
"basic expired",
"", // autogen
Expand Down Expand Up @@ -445,6 +435,89 @@ func TestParser_ParseUnverified(t *testing.T) {
}
}

var setPaddingTestData = []struct {
name string
tokenString string
claims jwt.Claims
paddedDecode uint64
signingMethod jwt.SigningMethod
keyfunc jwt.Keyfunc
valid bool
}{
{
name: "Validated non-padded token with padding disabled",
tokenString: "",
claims: jwt.MapClaims{"foo": "paddedbar"},
paddedDecode: jwt.DisablePadding,
signingMethod: jwt.SigningMethodRS256,
keyfunc: defaultKeyFunc,
valid: true,
},
{
name: "Validated non-padded token with padding enabled",
tokenString: "",
claims: jwt.MapClaims{"foo": "paddedbar"},
paddedDecode: jwt.AllowPadding,
signingMethod: jwt.SigningMethodRS256,
keyfunc: defaultKeyFunc,
valid: true,
},
{
name: "Error for padded token with padding disabled",
tokenString: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJwYWRkZWRiYXIifQ==.20kGGJaYekGTRFf8b0TwhuETcR8lv5z2363X5jf7G1yTWVTwOmte5Ii8L8_OQbYwPoiVHmZY6iJPbt_DhCN42AeFY74BcsUhR-BVrYUVhKK0RppuzEcSlILDNeQsJDLEL035CPm1VO6Jrgk7enQPIctVxUesRgswP71OpGvJxy3j1k_J8p0WzZvRZTe1D_2Misa0UDGwnEIHhmr97fIpMSZjFxlcygQw8QN34IHLHIXMaTY1eiCf4CCr6rOS9wUeu7P3CPkmFq9XhxBT_LLCmIMhHnxP5x27FUJE_JZlfek0MmARcrhpsZS2sFhHAiWrjxjOE27jkDtv1nEwn65wMw==",
claims: jwt.MapClaims{"foo": "paddedbar"},
paddedDecode: jwt.DisablePadding,
signingMethod: jwt.SigningMethodRS256,
keyfunc: defaultKeyFunc,
valid: false,
},
{
name: "Validated padded token with padding enabled",
tokenString: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJwYWRkZWRiYXIifQ==.20kGGJaYekGTRFf8b0TwhuETcR8lv5z2363X5jf7G1yTWVTwOmte5Ii8L8_OQbYwPoiVHmZY6iJPbt_DhCN42AeFY74BcsUhR-BVrYUVhKK0RppuzEcSlILDNeQsJDLEL035CPm1VO6Jrgk7enQPIctVxUesRgswP71OpGvJxy3j1k_J8p0WzZvRZTe1D_2Misa0UDGwnEIHhmr97fIpMSZjFxlcygQw8QN34IHLHIXMaTY1eiCf4CCr6rOS9wUeu7P3CPkmFq9XhxBT_LLCmIMhHnxP5x27FUJE_JZlfek0MmARcrhpsZS2sFhHAiWrjxjOE27jkDtv1nEwn65wMw==",
claims: jwt.MapClaims{"foo": "paddedbar"},
paddedDecode: jwt.AllowPadding,
signingMethod: jwt.SigningMethodRS256,
keyfunc: defaultKeyFunc,
valid: true,
},
}

// Extension of Parsing, this is to test out functionality specific to switching codecs with padding.
func TestSetPadding(t *testing.T) {
for _, data := range setPaddingTestData {
t.Run(data.name, func(t *testing.T) {

// If the token string is blank, use helper function to generate string
jwt.SetDecodePadding(data.paddedDecode)

if data.tokenString == "" {
data.tokenString = signToken(data.claims, data.signingMethod)

}
fmt.Println(data.tokenString)

// Parse the token
var token *jwt.Token
var err error
parser := new(jwt.Parser)

// Figure out correct claims type
token, err = parser.ParseWithClaims(data.tokenString, jwt.MapClaims{}, data.keyfunc)

if (err == nil) != data.valid || token.Valid != data.valid {
t.Errorf("[%v] Error Parsing Token with decoding padding set to %v: %v",
data.name,
data.paddedDecode,
err,
)
}

})
jwt.SetDecodePadding(jwt.DisablePadding)

}
}

func BenchmarkParseUnverified(b *testing.B) {

// Iterate over test data set and run tests
Expand Down
26 changes: 25 additions & 1 deletion token.go
Expand Up @@ -4,9 +4,30 @@ import (
"encoding/base64"
"encoding/json"
"strings"
"sync/atomic"
"time"
)

const (
DisablePadding uint64 = 0 // Utilizes RawURLEncoding
AllowPadding uint64 = 1 // Utilizes URLEncoding

)

var decodePaddingAllowed uint64

// SetDecodePadding will switch the codec used for encoding/decoding JWTs respectively. Note that the JWS RFC7515
// states that the tokens will utilize a Base64url encoding with no padding. Unfortuneately, some implementations
// of JWT are producing non-standard tokens, and thus require support for decoding. Note that this is a global
// variable, and updating it will change the behavior on a package level.
func SetDecodePadding(setPadding uint64) {
atomic.SwapUint64(&decodePaddingAllowed, setPadding)
}

func init() {
SetDecodePadding(DisablePadding)
}

// TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time).
// You can override it to use another time value. This is useful for testing or if your
// server uses a different time zone than your tokens.
Expand Down Expand Up @@ -112,7 +133,10 @@ func EncodeSegment(seg []byte) string {
// Deprecated: In a future release, we will demote this function to a non-exported function, since it
// should only be used internally
func DecodeSegment(seg string) ([]byte, error) {
if strings.Contains(seg, "=") {
if atomic.LoadUint64(&decodePaddingAllowed) == AllowPadding {
if l := len(seg) % 4; l > 0 {
seg += strings.Repeat("=", 4-l)
}
return base64.URLEncoding.DecodeString(seg)
}

Expand Down

0 comments on commit 25379bc

Please sign in to comment.