diff --git a/go.mod b/go.mod index 42d5ac7..8fbd826 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/gin-gonic/gin v1.9.1 github.com/go-redis/redis/v8 v8.11.5 github.com/go-redis/redis_rate/v9 v9.1.2 - github.com/golang-jwt/jwt v3.2.2+incompatible + github.com/golang-jwt/jwt/v5 v5.0.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.17.0 github.com/rs/zerolog v1.31.0 diff --git a/go.sum b/go.sum index 1815590..d588a41 100644 --- a/go.sum +++ b/go.sum @@ -276,8 +276,8 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= +github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= diff --git a/token/token.go b/token/token.go index 20a83db..6128c37 100644 --- a/token/token.go +++ b/token/token.go @@ -6,7 +6,7 @@ import ( "time" "github.com/elisasre/go-common" - "github.com/golang-jwt/jwt" + "github.com/golang-jwt/jwt/v5" ) // Token struct. @@ -45,7 +45,7 @@ func New(user *common.User) *Token { // UserJWTClaims contains struct for making and parsing jwt tokens. type UserJWTClaims struct { *common.User - jwt.StandardClaims + jwt.RegisteredClaims Nonce string `json:"nonce,omitempty"` } @@ -80,12 +80,12 @@ func (t *Token) SignExpires(key common.JWTKey, claim SignClaims) (string, error) claims := UserJWTClaims{ t.User, - jwt.StandardClaims{ + jwt.RegisteredClaims{ Subject: sub, - Audience: claim.Aud, - ExpiresAt: claim.Exp, + Audience: jwt.ClaimStrings{claim.Aud}, + ExpiresAt: jwt.NewNumericDate(time.Unix(claim.Exp, 0)), Issuer: claim.Issuer, - IssuedAt: claim.Iat, + IssuedAt: jwt.NewNumericDate(time.Unix(claim.Iat, 0)), }, claim.Nonce, } @@ -119,7 +119,7 @@ func findKidFromArray(keys []common.JWTKey, kid interface{}) (common.JWTKey, err } // Parse will validate jwt token and return token. -func Parse(raw string, keys []common.JWTKey) (*UserJWTClaims, error) { +func Parse(raw string, keys []common.JWTKey, options ...jwt.ParserOption) (*UserJWTClaims, error) { parsed, err := jwt.ParseWithClaims(raw, &UserJWTClaims{}, func(t *jwt.Token) (interface{}, error) { if t.Method.Alg() != SignAlgo { return nil, jwt.ErrSignatureInvalid @@ -132,11 +132,11 @@ func Parse(raw string, keys []common.JWTKey) (*UserJWTClaims, error) { return key.PublicKey, nil } return nil, fmt.Errorf("could not find kid from headers") - }) + }, options...) if err != nil { return nil, err } else if !parsed.Valid { - return nil, jwt.ValidationError{} + return nil, fmt.Errorf("jwt token was not valid") } claims, ok := parsed.Claims.(*UserJWTClaims) diff --git a/token/token_test.go b/token/token_test.go index 8683f48..647329d 100644 --- a/token/token_test.go +++ b/token/token_test.go @@ -7,6 +7,7 @@ import ( "time" "github.com/elisasre/go-common" + "github.com/golang-jwt/jwt/v5" "github.com/stretchr/testify/require" ) @@ -127,7 +128,7 @@ func TestInvalidKid(t *testing.T) { }) require.NoError(t, err) _, err = Parse(token, []common.JWTKey{*key2}) - require.Equal(t, fmt.Sprintf("could not find kid '%s'", key.KID), err.Error()) + require.Contains(t, err.Error(), fmt.Sprintf("could not find kid '%s'", key.KID)) } func TestExpired(t *testing.T) { @@ -143,5 +144,23 @@ func TestExpired(t *testing.T) { }) require.NoError(t, err) _, err = Parse(token, []common.JWTKey{*key}) - require.True(t, strings.HasPrefix(err.Error(), "token is expired by")) + require.Contains(t, err.Error(), "token is expired") +} + +func TestIssuer(t *testing.T) { + key, err := common.GenerateNewKeyPair() + require.NoError(t, err) + + testUser := New(&common.User{}) + token, err := testUser.SignExpires(*key, SignClaims{ + Aud: "internal", + Exp: time.Now().Add(time.Hour).Unix(), + Issuer: "http://localhost", + Scopes: AllScopes, + }) + require.NoError(t, err) + _, err = Parse(token, []common.JWTKey{*key}, jwt.WithIssuer("http://foobar")) + require.True(t, strings.Contains(err.Error(), "token has invalid issuer")) + _, err = Parse(token, []common.JWTKey{*key}, jwt.WithIssuer("http://localhost")) + require.NoError(t, err) }