Remove `StandardClaims` in favor of `RegisteredClaims` (#235)

This PR removes the old legacy standard claims, which have been deprecated since the beginning of the `v4` module in favor of the newer `RegisteredClaims`. Removing them before any further changes to the validation API is quite useful, as less code needs to be adapated.
This commit is contained in:
Christian Banse 2022-08-28 18:17:04 +02:00 committed by GitHub
parent 895749e449
commit 7e82f33cee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 5 additions and 118 deletions

View File

@ -119,102 +119,6 @@ func (c *RegisteredClaims) VerifyIssuer(cmp string, req bool) bool {
return verifyIss(c.Issuer, cmp, req) return verifyIss(c.Issuer, cmp, req)
} }
// StandardClaims are a structured version of the JWT Claims Set, as referenced at
// https://datatracker.ietf.org/doc/html/rfc7519#section-4. They do not follow the
// specification exactly, since they were based on an earlier draft of the
// specification and not updated. The main difference is that they only
// support integer-based date fields and singular audiences. This might lead to
// incompatibilities with other JWT implementations. The use of this is discouraged, instead
// the newer RegisteredClaims struct should be used.
//
// Deprecated: Use RegisteredClaims instead for a forward-compatible way to access registered claims in a struct.
type StandardClaims struct {
Audience string `json:"aud,omitempty"`
ExpiresAt int64 `json:"exp,omitempty"`
Id string `json:"jti,omitempty"`
IssuedAt int64 `json:"iat,omitempty"`
Issuer string `json:"iss,omitempty"`
NotBefore int64 `json:"nbf,omitempty"`
Subject string `json:"sub,omitempty"`
}
// Valid validates time based claims "exp, iat, nbf". There is no accounting for clock skew.
// As well, if any of the above claims are not in the token, it will still
// be considered a valid claim.
func (c StandardClaims) Valid() error {
vErr := new(ValidationError)
now := TimeFunc().Unix()
// The claims below are optional, by default, so if they are set to the
// default value in Go, let's not fail the verification for them.
if !c.VerifyExpiresAt(now, false) {
delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0))
vErr.Inner = fmt.Errorf("%s by %s", ErrTokenExpired, delta)
vErr.Errors |= ValidationErrorExpired
}
if !c.VerifyIssuedAt(now, false) {
vErr.Inner = ErrTokenUsedBeforeIssued
vErr.Errors |= ValidationErrorIssuedAt
}
if !c.VerifyNotBefore(now, false) {
vErr.Inner = ErrTokenNotValidYet
vErr.Errors |= ValidationErrorNotValidYet
}
if vErr.valid() {
return nil
}
return vErr
}
// VerifyAudience compares the aud claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool {
return verifyAud([]string{c.Audience}, cmp, req)
}
// VerifyExpiresAt compares the exp claim against cmp (cmp < exp).
// If req is false, it will return true, if exp is unset.
func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool {
if c.ExpiresAt == 0 {
return verifyExp(nil, time.Unix(cmp, 0), req)
}
t := time.Unix(c.ExpiresAt, 0)
return verifyExp(&t, time.Unix(cmp, 0), req)
}
// VerifyIssuedAt compares the iat claim against cmp (cmp >= iat).
// If req is false, it will return true, if iat is unset.
func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool {
if c.IssuedAt == 0 {
return verifyIat(nil, time.Unix(cmp, 0), req)
}
t := time.Unix(c.IssuedAt, 0)
return verifyIat(&t, time.Unix(cmp, 0), req)
}
// VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf).
// If req is false, it will return true, if nbf is unset.
func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {
if c.NotBefore == 0 {
return verifyNbf(nil, time.Unix(cmp, 0), req)
}
t := time.Unix(c.NotBefore, 0)
return verifyNbf(&t, time.Unix(cmp, 0), req)
}
// VerifyIssuer compares the iss claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool {
return verifyIss(c.Issuer, cmp, req)
}
// ----- helpers // ----- helpers
func verifyAud(aud []string, cmp string, required bool) bool { func verifyAud(aud []string, cmp string, required bool) bool {

View File

@ -199,19 +199,6 @@ var jwtTestData = []struct {
&jwt.Parser{UseJSONNumber: true}, &jwt.Parser{UseJSONNumber: true},
jwt.SigningMethodRS256, jwt.SigningMethodRS256,
}, },
{
"Standard Claims",
"",
defaultKeyFunc,
&jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Second * 10).Unix(),
},
true,
0,
nil,
&jwt.Parser{UseJSONNumber: true},
jwt.SigningMethodRS256,
},
{ {
"JSON Number - basic expired", "JSON Number - basic expired",
"", // autogen "", // autogen
@ -360,8 +347,6 @@ func TestParser_Parse(t *testing.T) {
switch data.claims.(type) { switch data.claims.(type) {
case jwt.MapClaims: case jwt.MapClaims:
token, err = parser.ParseWithClaims(data.tokenString, jwt.MapClaims{}, data.keyfunc) token, err = parser.ParseWithClaims(data.tokenString, jwt.MapClaims{}, data.keyfunc)
case *jwt.StandardClaims:
token, err = parser.ParseWithClaims(data.tokenString, &jwt.StandardClaims{}, data.keyfunc)
case *jwt.RegisteredClaims: case *jwt.RegisteredClaims:
token, err = parser.ParseWithClaims(data.tokenString, &jwt.RegisteredClaims{}, data.keyfunc) token, err = parser.ParseWithClaims(data.tokenString, &jwt.RegisteredClaims{}, data.keyfunc)
} }
@ -454,8 +439,6 @@ func TestParser_ParseUnverified(t *testing.T) {
switch data.claims.(type) { switch data.claims.(type) {
case jwt.MapClaims: case jwt.MapClaims:
token, _, err = parser.ParseUnverified(data.tokenString, jwt.MapClaims{}) token, _, err = parser.ParseUnverified(data.tokenString, jwt.MapClaims{})
case *jwt.StandardClaims:
token, _, err = parser.ParseUnverified(data.tokenString, &jwt.StandardClaims{})
case *jwt.RegisteredClaims: case *jwt.RegisteredClaims:
token, _, err = parser.ParseUnverified(data.tokenString, &jwt.RegisteredClaims{}) token, _, err = parser.ParseUnverified(data.tokenString, &jwt.RegisteredClaims{})
} }
@ -605,9 +588,9 @@ func BenchmarkParseUnverified(b *testing.B) {
b.Run("map_claims", func(b *testing.B) { b.Run("map_claims", func(b *testing.B) {
benchmarkParsing(b, parser, data.tokenString, jwt.MapClaims{}) benchmarkParsing(b, parser, data.tokenString, jwt.MapClaims{})
}) })
case *jwt.StandardClaims: case *jwt.RegisteredClaims:
b.Run("standard_claims", func(b *testing.B) { b.Run("registered_claims", func(b *testing.B) {
benchmarkParsing(b, parser, data.tokenString, &jwt.StandardClaims{}) benchmarkParsing(b, parser, data.tokenString, &jwt.RegisteredClaims{})
}) })
} }
} }

View File

@ -30,7 +30,7 @@ func TestToken_SigningString(t1 *testing.T) {
"typ": "JWT", "typ": "JWT",
"alg": jwt.SigningMethodHS256.Alg(), "alg": jwt.SigningMethodHS256.Alg(),
}, },
Claims: jwt.StandardClaims{}, Claims: jwt.RegisteredClaims{},
Signature: "", Signature: "",
Valid: false, Valid: false,
}, },
@ -67,7 +67,7 @@ func BenchmarkToken_SigningString(b *testing.B) {
"typ": "JWT", "typ": "JWT",
"alg": jwt.SigningMethodHS256.Alg(), "alg": jwt.SigningMethodHS256.Alg(),
}, },
Claims: jwt.StandardClaims{}, Claims: jwt.RegisteredClaims{},
} }
b.Run("BenchmarkToken_SigningString", func(b *testing.B) { b.Run("BenchmarkToken_SigningString", func(b *testing.B) {
b.ResetTimer() b.ResetTimer()