From e04af6c7bd8a217e1ee9debe186f16384c2febfe Mon Sep 17 00:00:00 2001 From: Chris Moran Date: Wed, 3 Jul 2024 07:21:42 -0400 Subject: [PATCH 1/2] feat: support multiple issuer:audience combinations by introducing an option for the expectedClaims. WithExpectedClaims can be called with multiple jwt.Expected parameters to allow different Issuer:Audience combinations to validate tokens feat: support multiple issuers in a provider using WithAdditionalIssuers option Every effort has been made to ensure backwards compatibility. Some error messages will be different due to the wrapping of errors when multiple jwt.Expected are set. When validating the jwt, if an error is encountered, instead of returning immediately, the current error is wrapped. This is good and bad. Good because all verification failure causes are captured in a single wrapped error; Bad because all verification failure causes are captured in a single monolithic wrapped error. Unwrapping the error can be tedious if many jwt.Expected are included. There is likely a better way but this suits my purposes. A few more test cases will likely be needed in order to achieve true confidence in this change --- README.md | 1 - examples/echo-example/README.md | 1 + examples/echo-example/go.mod | 1 + examples/echo-example/main.go | 8 +- examples/echo-example/middleware.go | 2 +- examples/gin-example/README.md | 1 + examples/gin-example/go.mod | 3 +- examples/gin-example/main.go | 62 +++- examples/gin-example/middleware.go | 56 +++- examples/http-example/README.md | 1 + examples/http-example/go.mod | 2 +- examples/http-example/main.go | 13 +- examples/http-example/main_test.go | 6 +- examples/http-jwks-example/go.mod | 2 +- examples/http-jwks-example/main.go | 3 +- examples/http-jwks-example/main_test.go | 6 +- examples/iris-example/README.md | 1 + examples/iris-example/go.mod | 3 +- examples/iris-example/main.go | 8 +- examples/iris-example/middleware.go | 2 +- extractor.go | 4 +- extractor_test.go | 2 +- go.mod | 2 +- jwks/provider.go | 63 ++++- jwks/provider_test.go | 2 +- middleware_test.go | 5 +- validator/option.go | 14 + validator/validator.go | 178 +++++++++--- validator/validator_test.go | 359 ++++++++++++++++++++++-- 29 files changed, 692 insertions(+), 119 deletions(-) diff --git a/README.md b/README.md index f8fa478b..dd2588c4 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,6 @@ import ( "log" "net/http" - "github.com/auth0/go-jwt-middleware/v2" "github.com/auth0/go-jwt-middleware/v2/validator" jwtmiddleware "github.com/auth0/go-jwt-middleware/v2" ) diff --git a/examples/echo-example/README.md b/examples/echo-example/README.md index 8822ef6a..6e455ead 100644 --- a/examples/echo-example/README.md +++ b/examples/echo-example/README.md @@ -10,3 +10,4 @@ To try this out: * Run `go run .` to start the app. * Use [jwt.io](https://jwt.io/) to generate a JWT signed with the HS256 algorithm and `secret`. * Call `http://localhost:3000` with the JWT to get a response back. +* see `main.go` for example tokens diff --git a/examples/echo-example/go.mod b/examples/echo-example/go.mod index 8b9bec3b..9f3b1854 100644 --- a/examples/echo-example/go.mod +++ b/examples/echo-example/go.mod @@ -12,6 +12,7 @@ require ( replace github.com/auth0/go-jwt-middleware/v2 => ./../../ require ( + github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/examples/echo-example/main.go b/examples/echo-example/main.go index 59b0fb77..1d8a4f5e 100644 --- a/examples/echo-example/main.go +++ b/examples/echo-example/main.go @@ -11,9 +11,9 @@ import ( // Try it out with: // -// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyJ9.XFhrzWzntyINkgoRt2mb8dES84dJcuOoORdzKfwUX70 +// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyJ9.DSY4NlpZZ2mOqaKuXvJkOrgZA3nD5HuGaf1wB9-0OVw // -// which is signed with 'secret' and has the data: +// which is signed with 'abcdefghijklmnopqrstuvwxyz012345' and has the data: // // { // "iss": "go-jwt-middleware-example", @@ -26,9 +26,9 @@ import ( // // You can also try out the custom validation with: // -// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyIsInNob3VsZFJlamVjdCI6dHJ1ZX0.Jf13PY_Oyu2x3Gx1JQ0jXRiWaCOb5T2RbKOrTPBNHJA +// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyIsInNob3VsZFJlamVjdCI6dHJ1ZX0.qjjJBgKNomlbEQrCobpEU9ASgvSpLQhQBryRkp6-RQc // -// which is signed with 'secret' and has the data: +// which is signed with 'abcdefghijklmnopqrstuvwxyz012345' and has the data: // // { // "iss": "go-jwt-middleware-example", diff --git a/examples/echo-example/middleware.go b/examples/echo-example/middleware.go index d81d518a..14272921 100644 --- a/examples/echo-example/middleware.go +++ b/examples/echo-example/middleware.go @@ -13,7 +13,7 @@ import ( var ( // The signing key for the token. - signingKey = []byte("secret") + signingKey = []byte("abcdefghijklmnopqrstuvwxyz012345") // The issuer of our token. issuer = "go-jwt-middleware-example" diff --git a/examples/gin-example/README.md b/examples/gin-example/README.md index 927b718a..6c0be1fc 100644 --- a/examples/gin-example/README.md +++ b/examples/gin-example/README.md @@ -10,3 +10,4 @@ To try this out: * Run `go run .` to start the app. * Use [jwt.io](https://jwt.io/) to generate a JWT signed with the HS256 algorithm and `secret`. * Call `http://localhost:3000` with the JWT to get a response back. +* see `main.go` for example tokens diff --git a/examples/gin-example/go.mod b/examples/gin-example/go.mod index 413ae2df..975c0138 100644 --- a/examples/gin-example/go.mod +++ b/examples/gin-example/go.mod @@ -4,7 +4,8 @@ go 1.23.0 require ( github.com/auth0/go-jwt-middleware/v2 v2.2.2 - github.com/gin-gonic/gin v1.9.1 + github.com/gin-gonic/gin v1.10.0 + github.com/go-jose/go-jose/v4 v4.0.4 ) replace github.com/auth0/go-jwt-middleware/v2 => ./../../ diff --git a/examples/gin-example/main.go b/examples/gin-example/main.go index 03cc34e2..7547eb04 100644 --- a/examples/gin-example/main.go +++ b/examples/gin-example/main.go @@ -11,9 +11,9 @@ import ( // Try it out with: // -// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyJ9.XFhrzWzntyINkgoRt2mb8dES84dJcuOoORdzKfwUX70 +// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyJ9.DSY4NlpZZ2mOqaKuXvJkOrgZA3nD5HuGaf1wB9-0OVw // -// which is signed with 'secret' and has the data: +// which is signed with 'abcdefghijklmnopqrstuvwxyz012345' and has the data: // // { // "iss": "go-jwt-middleware-example", @@ -26,9 +26,9 @@ import ( // // You can also try out the custom validation with: // -// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyIsInNob3VsZFJlamVjdCI6dHJ1ZX0.Jf13PY_Oyu2x3Gx1JQ0jXRiWaCOb5T2RbKOrTPBNHJA +// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyIsInNob3VsZFJlamVjdCI6dHJ1ZX0.qjjJBgKNomlbEQrCobpEU9ASgvSpLQhQBryRkp6-RQc // -// which is signed with 'secret' and has the data: +// which is signed with 'abcdefghijklmnopqrstuvwxyz012345' and has the data: // // { // "iss": "go-jwt-middleware-example", @@ -39,9 +39,29 @@ import ( // "username": "user123", // "shouldReject": true // } +// +// You can also try out the /multiple endpoint. This endpoint accepts tokens signed by multiple issuers. Try the +// token below which has a different issuer: +// +// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1tdWx0aXBsZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtbXVsdGlwbGUtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyJ9.d0BmhdqVZ9IdqQNId3XI2kbTegwW5NYe9P4xQCOjQ1Y +// +// which is signed with 'abcdefghijklmnopqrstuvwxyz012345' and has the data: +// +// { +// "iss": "go-jwt-middleware-multiple-example", +// "aud": "audience-multiple-example", +// "sub": "1234567890", +// "name": "John Doe", +// "iat": 1516239022, +// "username": "user123" +// } +// +// You can also try the previous tokens with the /multiple endpoint. The first token will be valid the second will fail because +// the custom validator rejects it (shouldReject: true) func main() { router := gin.Default() + router.GET("/", checkJWT(), func(ctx *gin.Context) { claims, ok := ctx.Request.Context().Value(jwtmiddleware.ContextKey{}).(*validator.ValidatedClaims) if !ok { @@ -52,7 +72,37 @@ func main() { return } - customClaims, ok := claims.CustomClaims.(*CustomClaimsExample) + localCustomClaims, ok := claims.CustomClaims.(*CustomClaimsExample) + if !ok { + ctx.AbortWithStatusJSON( + http.StatusInternalServerError, + map[string]string{"message": "Failed to cast custom JWT claims to specific type."}, + ) + return + } + + if len(localCustomClaims.Username) == 0 { + ctx.AbortWithStatusJSON( + http.StatusBadRequest, + map[string]string{"message": "Username in JWT claims was empty."}, + ) + return + } + + ctx.JSON(http.StatusOK, claims) + }) + + router.GET("/multiple", checkJWTMultiple(), func(ctx *gin.Context) { + claims, ok := ctx.Request.Context().Value(jwtmiddleware.ContextKey{}).(*validator.ValidatedClaims) + if !ok { + ctx.AbortWithStatusJSON( + http.StatusInternalServerError, + map[string]string{"message": "Failed to get validated JWT claims."}, + ) + return + } + + localCustomClaims, ok := claims.CustomClaims.(*CustomClaimsExample) if !ok { ctx.AbortWithStatusJSON( http.StatusInternalServerError, @@ -61,7 +111,7 @@ func main() { return } - if len(customClaims.Username) == 0 { + if len(localCustomClaims.Username) == 0 { ctx.AbortWithStatusJSON( http.StatusBadRequest, map[string]string{"message": "Username in JWT claims was empty."}, diff --git a/examples/gin-example/middleware.go b/examples/gin-example/middleware.go index 104cd07c..8ea4cf54 100644 --- a/examples/gin-example/middleware.go +++ b/examples/gin-example/middleware.go @@ -2,6 +2,7 @@ package main import ( "context" + "github.com/go-jose/go-jose/v4/jwt" "log" "net/http" "time" @@ -13,13 +14,15 @@ import ( var ( // The signing key for the token. - signingKey = []byte("secret") + signingKey = []byte("abcdefghijklmnopqrstuvwxyz012345") // The issuer of our token. - issuer = "go-jwt-middleware-example" + issuer = "go-jwt-middleware-example" + issuerTwo = "go-jwt-middleware-multiple-example" // The audience of our token. - audience = []string{"audience-example"} + audience = []string{"audience-example"} + audienceTwo = []string{"audience-multiple-example"} // Our token must be signed using this data. keyFunc = func(ctx context.Context) (interface{}, error) { @@ -76,3 +79,50 @@ func checkJWT() gin.HandlerFunc { } } } + +func checkJWTMultiple() gin.HandlerFunc { + // Set up the validator. + jwtValidator, err := validator.NewValidator( + keyFunc, + validator.HS256, + validator.WithCustomClaims(customClaims), + validator.WithAllowedClockSkew(30*time.Second), + validator.WithExpectedClaims(jwt.Expected{ + Issuer: issuer, + AnyAudience: audience, + }, jwt.Expected{ + Issuer: issuerTwo, + AnyAudience: audienceTwo, + }), + ) + if err != nil { + log.Fatalf("failed to set up the validator: %v", err) + } + + errorHandler := func(w http.ResponseWriter, r *http.Request, err error) { + log.Printf("Encountered error while validating JWT: %v", err) + } + + middleware := jwtmiddleware.New( + jwtValidator.ValidateToken, + jwtmiddleware.WithErrorHandler(errorHandler), + ) + + return func(ctx *gin.Context) { + encounteredError := true + var handler http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) { + encounteredError = false + ctx.Request = r + ctx.Next() + } + + middleware.CheckJWT(handler).ServeHTTP(ctx.Writer, ctx.Request) + + if encounteredError { + ctx.AbortWithStatusJSON( + http.StatusUnauthorized, + map[string]string{"message": "JWT is invalid."}, + ) + } + } +} diff --git a/examples/http-example/README.md b/examples/http-example/README.md index c382f480..feb8d2d7 100644 --- a/examples/http-example/README.md +++ b/examples/http-example/README.md @@ -10,3 +10,4 @@ To try this out: * Run `go run main.go` to start the app. * Use [jwt.io](https://jwt.io/) to generate a JWT signed with the HS256 algorithm and `secret`. * Call `http://localhost:3000` with the JWT to get a response back. +* see `main.go` for example tokens diff --git a/examples/http-example/go.mod b/examples/http-example/go.mod index 173adfad..c1f43a72 100644 --- a/examples/http-example/go.mod +++ b/examples/http-example/go.mod @@ -4,7 +4,7 @@ go 1.23.0 require ( github.com/auth0/go-jwt-middleware/v2 v2.2.2 - gopkg.in/go-jose/go-jose.v2 v2.6.3 + github.com/go-jose/go-jose/v4 v4.0.4 ) replace github.com/auth0/go-jwt-middleware/v2 => ./../../ diff --git a/examples/http-example/main.go b/examples/http-example/main.go index b7ad5eb9..5cc8e894 100644 --- a/examples/http-example/main.go +++ b/examples/http-example/main.go @@ -8,13 +8,12 @@ import ( "net/http" "time" - "github.com/auth0/go-jwt-middleware/v2" - "github.com/auth0/go-jwt-middleware/v2/validator" jwtmiddleware "github.com/auth0/go-jwt-middleware/v2" + "github.com/auth0/go-jwt-middleware/v2/validator" ) var ( - signingKey = []byte("secret") + signingKey = []byte("abcdefghijklmnopqrstuvwxyz012345") issuer = "go-jwt-middleware-example" audience = []string{"audience-example"} ) @@ -94,9 +93,9 @@ func main() { // Try it out with: // - // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyJ9.XFhrzWzntyINkgoRt2mb8dES84dJcuOoORdzKfwUX70 + // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyJ9.DSY4NlpZZ2mOqaKuXvJkOrgZA3nD5HuGaf1wB9-0OVw // - // which is signed with 'secret' and has the data: + // which is signed with 'abcdefghijklmnopqrstuvwxyz012345' and has the data: // { // "iss": "go-jwt-middleware-example", // "aud": "audience-example", @@ -108,9 +107,9 @@ func main() { // // You can also try out the custom validation with: // - // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyIsInNob3VsZFJlamVjdCI6dHJ1ZX0.Jf13PY_Oyu2x3Gx1JQ0jXRiWaCOb5T2RbKOrTPBNHJA + // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyIsInNob3VsZFJlamVjdCI6dHJ1ZX0.qjjJBgKNomlbEQrCobpEU9ASgvSpLQhQBryRkp6-RQc // - // which is signed with 'secret' and has the data: + // which is signed with 'abcdefghijklmnopqrstuvwxyz012345' and has the data: // { // "iss": "go-jwt-middleware-example", // "aud": "audience-example", diff --git a/examples/http-example/main_test.go b/examples/http-example/main_test.go index 81ea91c1..3ce6ca50 100644 --- a/examples/http-example/main_test.go +++ b/examples/http-example/main_test.go @@ -5,8 +5,8 @@ import ( "net/http/httptest" "testing" - "gopkg.in/go-jose/go-jose.v2" - "gopkg.in/go-jose/go-jose.v2/jwt" + "github.com/go-jose/go-jose/v4" + "github.com/go-jose/go-jose/v4/jwt" ) func TestHandler(t *testing.T) { @@ -70,7 +70,7 @@ func buildJWTForTesting(t *testing.T, username string) string { Username: username, } - token, err := jwt.Signed(signer).Claims(claims).Claims(customClaims).CompactSerialize() + token, err := jwt.Signed(signer).Claims(claims).Claims(customClaims).Serialize() if err != nil { t.Fatalf("could not build token: %s", err.Error()) } diff --git a/examples/http-jwks-example/go.mod b/examples/http-jwks-example/go.mod index 74e2b507..7b5c37d4 100644 --- a/examples/http-jwks-example/go.mod +++ b/examples/http-jwks-example/go.mod @@ -4,7 +4,7 @@ go 1.23.0 require ( github.com/auth0/go-jwt-middleware/v2 v2.2.2 - gopkg.in/go-jose/go-jose.v2 v2.6.3 + github.com/go-jose/go-jose/v4 v4.0.4 ) replace github.com/auth0/go-jwt-middleware/v2 => ./../../ diff --git a/examples/http-jwks-example/main.go b/examples/http-jwks-example/main.go index 81776dcc..93ee1440 100644 --- a/examples/http-jwks-example/main.go +++ b/examples/http-jwks-example/main.go @@ -7,10 +7,9 @@ import ( "net/url" "time" - "github.com/auth0/go-jwt-middleware/v2" + jwtmiddleware "github.com/auth0/go-jwt-middleware/v2" "github.com/auth0/go-jwt-middleware/v2/jwks" "github.com/auth0/go-jwt-middleware/v2/validator" - jwtmiddleware "github.com/auth0/go-jwt-middleware/v2" ) var handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/examples/http-jwks-example/main_test.go b/examples/http-jwks-example/main_test.go index 74d387dc..9fa0db9a 100644 --- a/examples/http-jwks-example/main_test.go +++ b/examples/http-jwks-example/main_test.go @@ -8,8 +8,8 @@ import ( "net/http/httptest" "testing" - "gopkg.in/go-jose/go-jose.v2" - "gopkg.in/go-jose/go-jose.v2/jwt" + "github.com/go-jose/go-jose/v4" + "github.com/go-jose/go-jose/v4/jwt" ) func TestHandler(t *testing.T) { @@ -120,7 +120,7 @@ func buildJWTForTesting(t *testing.T, jwk *jose.JSONWebKey, issuer, subject stri Subject: subject, } - token, err := jwt.Signed(signer).Claims(claims).CompactSerialize() + token, err := jwt.Signed(signer).Claims(claims).Serialize() if err != nil { t.Fatalf("could not build token: %s", err.Error()) } diff --git a/examples/iris-example/README.md b/examples/iris-example/README.md index 37ec0bdb..e5e84725 100644 --- a/examples/iris-example/README.md +++ b/examples/iris-example/README.md @@ -10,3 +10,4 @@ To try this out: * Run `go run .` to start the app. * Use [jwt.io](https://jwt.io/) to generate a JWT signed with the HS256 algorithm and `secret`. * Call `http://localhost:3000` with the JWT to get a response back. +* see `main.go` for example tokens diff --git a/examples/iris-example/go.mod b/examples/iris-example/go.mod index 13381cf5..ea4963f8 100644 --- a/examples/iris-example/go.mod +++ b/examples/iris-example/go.mod @@ -10,7 +10,7 @@ require ( replace github.com/auth0/go-jwt-middleware/v2 => ./../../ require ( - github.com/BurntSushi/toml v1.3.2 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect github.com/CloudyKit/jet/v6 v6.2.0 // indirect github.com/Joker/jade v1.1.3 // indirect @@ -19,6 +19,7 @@ require ( github.com/aymerick/douceur v0.2.0 // indirect github.com/fatih/structs v1.1.0 // indirect github.com/flosch/pongo2/v4 v4.0.2 // indirect + github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/gomarkdown/markdown v0.0.0-20250207164621-7a1f277a159e // indirect github.com/google/uuid v1.6.0 // indirect diff --git a/examples/iris-example/main.go b/examples/iris-example/main.go index ce1e949c..1acc08fe 100644 --- a/examples/iris-example/main.go +++ b/examples/iris-example/main.go @@ -10,9 +10,9 @@ import ( // Try it out with: // -// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyJ9.XFhrzWzntyINkgoRt2mb8dES84dJcuOoORdzKfwUX70 +// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyJ9.DSY4NlpZZ2mOqaKuXvJkOrgZA3nD5HuGaf1wB9-0OVw // -// which is signed with 'secret' and has the data: +// which is signed with 'abcdefghijklmnopqrstuvwxyz012345' and has the data: // // { // "iss": "go-jwt-middleware-example", @@ -25,9 +25,9 @@ import ( // // You can also try out the custom validation with: // -// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyIsInNob3VsZFJlamVjdCI6dHJ1ZX0.Jf13PY_Oyu2x3Gx1JQ0jXRiWaCOb5T2RbKOrTPBNHJA +// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnby1qd3QtbWlkZGxld2FyZS1leGFtcGxlIiwiYXVkIjoiYXVkaWVuY2UtZXhhbXBsZSIsInN1YiI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjIsInVzZXJuYW1lIjoidXNlcjEyMyIsInNob3VsZFJlamVjdCI6dHJ1ZX0.qjjJBgKNomlbEQrCobpEU9ASgvSpLQhQBryRkp6-RQc // -// which is signed with 'secret' and has the data: +// which is signed with 'abcdefghijklmnopqrstuvwxyz012345' and has the data: // // { // "iss": "go-jwt-middleware-example", diff --git a/examples/iris-example/middleware.go b/examples/iris-example/middleware.go index d27e4fae..b8ffea4c 100644 --- a/examples/iris-example/middleware.go +++ b/examples/iris-example/middleware.go @@ -13,7 +13,7 @@ import ( var ( // The signing key for the token. - signingKey = []byte("secret") + signingKey = []byte("abcdefghijklmnopqrstuvwxyz012345") // The issuer of our token. issuer = "go-jwt-middleware-example" diff --git a/extractor.go b/extractor.go index 376e513c..33882665 100644 --- a/extractor.go +++ b/extractor.go @@ -23,7 +23,7 @@ func AuthHeaderTokenExtractor(r *http.Request) (string, error) { authHeaderParts := strings.Fields(authHeader) if len(authHeaderParts) != 2 || strings.ToLower(authHeaderParts[0]) != "bearer" { - return "", errors.New("Authorization header format must be Bearer {token}") + return "", errors.New("authorization header format must be Bearer {token}") } return authHeaderParts[1], nil @@ -34,7 +34,7 @@ func AuthHeaderTokenExtractor(r *http.Request) (string, error) { func CookieTokenExtractor(cookieName string) TokenExtractor { return func(r *http.Request) (string, error) { cookie, err := r.Cookie(cookieName) - if err == http.ErrNoCookie { + if errors.Is(err, http.ErrNoCookie) { return "", nil // No cookie, then no JWT, so no error. } diff --git a/extractor_test.go b/extractor_test.go index 3101847d..adca0443 100644 --- a/extractor_test.go +++ b/extractor_test.go @@ -38,7 +38,7 @@ func Test_AuthHeaderTokenExtractor(t *testing.T) { "Authorization": []string{"i-am-a-token"}, }, }, - wantError: "Authorization header format must be Bearer {token}", + wantError: "authorization header format must be Bearer {token}", }, } diff --git a/go.mod b/go.mod index 0b61c02d..05ab4f15 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,10 @@ module github.com/auth0/go-jwt-middleware/v2 go 1.23.0 require ( + github.com/go-jose/go-jose/v4 v4.0.4 github.com/google/go-cmp v0.7.0 github.com/stretchr/testify v1.10.0 golang.org/x/sync v0.11.0 - gopkg.in/go-jose/go-jose.v2 v2.6.3 ) require ( diff --git a/jwks/provider.go b/jwks/provider.go index 40d4f784..198e1cd9 100644 --- a/jwks/provider.go +++ b/jwks/provider.go @@ -9,8 +9,8 @@ import ( "sync" "time" + "github.com/go-jose/go-jose/v4" "golang.org/x/sync/semaphore" - "gopkg.in/go-jose/go-jose.v2" "github.com/auth0/go-jwt-middleware/v2/internal/oidc" ) @@ -21,9 +21,10 @@ import ( // getting and caching JWKS which can help reduce request time and potential // rate limiting from your provider. type Provider struct { - IssuerURL *url.URL // Required. - CustomJWKSURI *url.URL // Optional. - Client *http.Client + IssuerURL *url.URL // Required. + CustomJWKSURI *url.URL // Optional. + AdditionalProviders []Provider // Optional + Client *http.Client } // ProviderOption is how options for the Provider are set up. @@ -32,14 +33,24 @@ type ProviderOption func(*Provider) // NewProvider builds and returns a new *Provider. func NewProvider(issuerURL *url.URL, opts ...ProviderOption) *Provider { p := &Provider{ - IssuerURL: issuerURL, - Client: &http.Client{}, + Client: &http.Client{}, + AdditionalProviders: make([]Provider, 0), + } + + if issuerURL != nil { + p.IssuerURL = issuerURL } for _, opt := range opts { opt(p) } + for _, provider := range p.AdditionalProviders { + if provider.Client == nil { + provider.Client = p.Client + } + } + return p } @@ -56,6 +67,21 @@ func WithCustomJWKSURI(jwksURI *url.URL) ProviderOption { func WithCustomClient(c *http.Client) ProviderOption { return func(p *Provider) { p.Client = c + for _, provider := range p.AdditionalProviders { + provider.Client = c + } + } +} + +// WithAdditionalProviders allows validation with mutliple IssuerURLs if desired. If multiple issuers are specified, +// a jwt may be signed by any of them and be considered valid +func WithAdditionalProviders(issuerURL *url.URL, customJWKSURI *url.URL) ProviderOption { + return func(p *Provider) { + p.AdditionalProviders = append(p.AdditionalProviders, Provider{ + IssuerURL: issuerURL, + CustomJWKSURI: customJWKSURI, + Client: p.Client, + }) } } @@ -63,6 +89,25 @@ func WithCustomClient(c *http.Client) ProviderOption { // While it returns an interface to adhere to keyFunc, as long as the // error is nil the type will be *jose.JSONWebKeySet. func (p *Provider) KeyFunc(ctx context.Context) (interface{}, error) { + rawJwks, err := p.keyFunc(ctx) + + if len(p.AdditionalProviders) == 0 { + return rawJwks, err + } else { + var jwks *jose.JSONWebKeySet + jwks = rawJwks.(*jose.JSONWebKeySet) + for _, provider := range p.AdditionalProviders { + if rawJwks, err = provider.keyFunc(ctx); err != nil { + continue + } else { + jwks.Keys = append(jwks.Keys, rawJwks.(*jose.JSONWebKeySet).Keys...) + } + } + return jwks, err + } +} + +func (p *Provider) keyFunc(ctx context.Context) (interface{}, error) { jwksURI := p.CustomJWKSURI if jwksURI == nil { wkEndpoints, err := oidc.GetWellKnownEndpointsFromIssuerURL(ctx, p.Client, *p.IssuerURL) @@ -85,10 +130,12 @@ func (p *Provider) KeyFunc(ctx context.Context) (interface{}, error) { if err != nil { return nil, err } - defer response.Body.Close() + defer func() { + _ = response.Body.Close() + }() var jwks jose.JSONWebKeySet - if err := json.NewDecoder(response.Body).Decode(&jwks); err != nil { + if err = json.NewDecoder(response.Body).Decode(&jwks); err != nil { return nil, fmt.Errorf("could not decode jwks: %w", err) } diff --git a/jwks/provider_test.go b/jwks/provider_test.go index 05484e78..ed494309 100644 --- a/jwks/provider_test.go +++ b/jwks/provider_test.go @@ -17,10 +17,10 @@ import ( "testing" "time" + "github.com/go-jose/go-jose/v4" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gopkg.in/go-jose/go-jose.v2" "github.com/auth0/go-jwt-middleware/v2/internal/oidc" ) diff --git a/middleware_test.go b/middleware_test.go index d195739c..9feb520b 100644 --- a/middleware_test.go +++ b/middleware_test.go @@ -17,7 +17,7 @@ import ( func Test_CheckJWT(t *testing.T) { const ( - validToken = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0SXNzdWVyIiwiYXVkIjoidGVzdEF1ZGllbmNlIn0.Bg8HXYXZ13zaPAcB0Bl0kRKW0iVF-2LTmITcEYUcWoo" + validToken = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0SXNzdWVyIiwiYXVkIjoidGVzdEF1ZGllbmNlIn0.Gyy_wLVaXohXo-QB1dgJWw-FbiS80mKw1OrTwmffvNo" invalidToken = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0aW5nIn0.eM1Jd7VA7nFSI09FlmLmtuv7cLnv8qicZ8s76-jTOoE" issuer = "testIssuer" audience = "testAudience" @@ -30,8 +30,9 @@ func Test_CheckJWT(t *testing.T) { }, } + secret := []byte("abcdefghijklmnopqrstuvwxyz012345") keyFunc := func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return secret, nil } jwtValidator, err := validator.New(keyFunc, validator.HS256, issuer, []string{audience}) diff --git a/validator/option.go b/validator/option.go index 12c1cc61..d95c41a8 100644 --- a/validator/option.go +++ b/validator/option.go @@ -1,6 +1,7 @@ package validator import ( + "github.com/go-jose/go-jose/v4/jwt" "time" ) @@ -26,3 +27,16 @@ func WithCustomClaims(f func() CustomClaims) Option { v.customClaims = f } } + +// WithExpectedClaims allows fine-grained customization of the expected claims +func WithExpectedClaims(expectedClaims ...jwt.Expected) Option { + return func(v *Validator) { + if len(expectedClaims) == 0 { + return + } + if v.expectedClaims == nil { + v.expectedClaims = make([]jwt.Expected, 0) + } + v.expectedClaims = append(v.expectedClaims, expectedClaims...) + } +} diff --git a/validator/validator.go b/validator/validator.go index 2a302493..0d02d5a4 100644 --- a/validator/validator.go +++ b/validator/validator.go @@ -4,9 +4,11 @@ import ( "context" "errors" "fmt" + "github.com/go-jose/go-jose/v4" + "strings" "time" - "gopkg.in/go-jose/go-jose.v2/jwt" + "github.com/go-jose/go-jose/v4/jwt" ) // Signature algorithms @@ -30,13 +32,14 @@ const ( type Validator struct { keyFunc func(context.Context) (interface{}, error) // Required. signatureAlgorithm SignatureAlgorithm // Required. - expectedClaims jwt.Expected // Internal. + expectedClaims []jwt.Expected // Internal. customClaims func() CustomClaims // Optional. allowedClockSkew time.Duration // Optional. } // SignatureAlgorithm is a signature algorithm. -type SignatureAlgorithm string +type SignatureAlgorithm jose.SignatureAlgorithm +type SignatureAlgorithms []jose.SignatureAlgorithm var allowedSigningAlgorithms = map[SignatureAlgorithm]bool{ EdDSA: true, @@ -66,11 +69,61 @@ func New( if keyFunc == nil { return nil, errors.New("keyFunc is required but was nil") } - if issuerURL == "" { - return nil, errors.New("issuer url is required but was empty") + if _, ok := allowedSigningAlgorithms[signatureAlgorithm]; !ok { + return nil, errors.New("unsupported signature algorithm") + } + + v := &Validator{ + keyFunc: keyFunc, + signatureAlgorithm: signatureAlgorithm, + expectedClaims: make([]jwt.Expected, 0), } - if len(audience) == 0 { + + for _, opt := range opts { + opt(v) + } + + if len(v.expectedClaims) == 0 && issuerURL == "" { + return nil, errors.New("issuer url is required but was empty") + } else if len(v.expectedClaims) == 0 && len(audience) == 0 { return nil, errors.New("audience is required but was empty") + } else if len(issuerURL) > 0 && len(audience) > 0 { + v.expectedClaims = append(v.expectedClaims, jwt.Expected{ + Issuer: issuerURL, + AnyAudience: audience, + }) + } + + if len(v.expectedClaims) == 0 { + return nil, errors.New("expected claims but none provided") + } + + for i, expected := range v.expectedClaims { + if expected.Issuer == "" { + return nil, fmt.Errorf("issuer url %d is required but was empty", i) + } + if len(expected.AnyAudience) == 0 { + return nil, fmt.Errorf("audience %d is required but was empty", i) + } + } + + return v, nil +} + +// NewValidator sets up a new Validator with the required keyFunc +// and signatureAlgorithm as well as custom options. +// This function has been added to provide an alternate function without the required issuer or audience parameters +// so they can be included in the opts parameter via WithExpectedClaims +// This function operates exactly like New with the exception of the two parameters issuer and audience and this function +// expects the inclusion of WithExpectedClaims with at least one valid expected claim. +// A valid expected claim would include an issuer and at least one audience +func NewValidator( + keyFunc func(context.Context) (interface{}, error), + signatureAlgorithm SignatureAlgorithm, + opts ...Option, +) (*Validator, error) { + if keyFunc == nil { + return nil, errors.New("keyFunc is required but was nil") } if _, ok := allowedSigningAlgorithms[signatureAlgorithm]; !ok { return nil, errors.New("unsupported signature algorithm") @@ -79,22 +132,32 @@ func New( v := &Validator{ keyFunc: keyFunc, signatureAlgorithm: signatureAlgorithm, - expectedClaims: jwt.Expected{ - Issuer: issuerURL, - Audience: audience, - }, + expectedClaims: make([]jwt.Expected, 0), } for _, opt := range opts { opt(v) } + if len(v.expectedClaims) == 0 { + return nil, errors.New("expected claims but none provided") + } + + for i, expected := range v.expectedClaims { + if expected.Issuer == "" { + return nil, fmt.Errorf("issuer url %d is required but was empty", i) + } + if len(expected.AnyAudience) == 0 { + return nil, fmt.Errorf("audience %d is required but was empty", i) + } + } + return v, nil } // ValidateToken validates the passed in JWT using the jose v2 package. func (v *Validator) ValidateToken(ctx context.Context, tokenString string) (interface{}, error) { - token, err := jwt.ParseSigned(tokenString) + token, err := jwt.ParseSigned(tokenString, signatureAlgorithms(v.signatureAlgorithm)) if err != nil { return nil, fmt.Errorf("could not parse the token: %w", err) } @@ -134,44 +197,81 @@ func (v *Validator) ValidateToken(ctx context.Context, tokenString string) (inte return validatedClaims, nil } -func validateClaimsWithLeeway(actualClaims jwt.Claims, expected jwt.Expected, leeway time.Duration) error { - expectedClaims := expected - expectedClaims.Time = time.Now() +func validateClaimsWithLeeway(actualClaims jwt.Claims, expectedIn []jwt.Expected, leeway time.Duration) error { + now := time.Now() + var currentError error + for _, expected := range expectedIn { + expectedClaims := expected + expectedClaims.Time = now - if actualClaims.Issuer != expectedClaims.Issuer { - return jwt.ErrInvalidIssuer - } + if actualClaims.Issuer != expectedClaims.Issuer { + currentError = createOrWrapError(currentError, jwt.ErrInvalidIssuer, actualClaims.Issuer, expectedClaims.Issuer) + continue + } - foundAudience := false - for _, value := range expectedClaims.Audience { - if actualClaims.Audience.Contains(value) { - foundAudience = true - break + foundAudience := false + for _, value := range expectedClaims.AnyAudience { + if actualClaims.Audience.Contains(value) { + foundAudience = true + break + } + } + if !foundAudience { + currentError = createOrWrapError( + currentError, + jwt.ErrInvalidAudience, + strings.Join(actualClaims.Audience, ","), + strings.Join(expectedClaims.AnyAudience, ","), + ) + continue } - } - if !foundAudience { - return jwt.ErrInvalidAudience - } - if actualClaims.NotBefore != nil && expectedClaims.Time.Add(leeway).Before(actualClaims.NotBefore.Time()) { - return jwt.ErrNotValidYet - } + if actualClaims.NotBefore != nil && expectedClaims.Time.Add(leeway).Before(actualClaims.NotBefore.Time()) { + return createOrWrapError( + currentError, + jwt.ErrNotValidYet, + actualClaims.NotBefore.Time().String(), + expectedClaims.Time.Add(leeway).String(), + ) + } + + if actualClaims.Expiry != nil && expectedClaims.Time.Add(-leeway).After(actualClaims.Expiry.Time()) { + return createOrWrapError( + currentError, + jwt.ErrExpired, + actualClaims.Expiry.Time().String(), + expectedClaims.Time.Add(leeway).String(), + ) + } - if actualClaims.Expiry != nil && expectedClaims.Time.Add(-leeway).After(actualClaims.Expiry.Time()) { - return jwt.ErrExpired + if actualClaims.IssuedAt != nil && expectedClaims.Time.Add(leeway).Before(actualClaims.IssuedAt.Time()) { + return createOrWrapError( + currentError, + jwt.ErrIssuedInTheFuture, + actualClaims.IssuedAt.Time().String(), + expectedClaims.Time.Add(leeway).String(), + ) + } + + return nil } - if actualClaims.IssuedAt != nil && expectedClaims.Time.Add(leeway).Before(actualClaims.IssuedAt.Time()) { - return jwt.ErrIssuedInTheFuture + return currentError +} + +func createOrWrapError(base, current error, actual, expected string) error { + if base == nil { + return current } - return nil + return errors.Join(base, fmt.Errorf("%v: %s vs %s", current, actual, expected)) } func validateSigningMethod(validAlg, tokenAlg string) error { if validAlg != tokenAlg { return fmt.Errorf("expected %q signing algorithm but token specified %q", validAlg, tokenAlg) } + return nil } @@ -208,5 +308,15 @@ func numericDateToUnixTime(date *jwt.NumericDate) int64 { if date != nil { return date.Time().Unix() } + return 0 } + +func signatureAlgorithms(algs ...SignatureAlgorithm) SignatureAlgorithms { + js := make(SignatureAlgorithms, len(algs)) + for i, alg := range algs { + js[i] = jose.SignatureAlgorithm(alg) + } + + return js +} diff --git a/validator/validator_test.go b/validator/validator_test.go index 08feeb14..511b4b80 100644 --- a/validator/validator_test.go +++ b/validator/validator_test.go @@ -7,9 +7,9 @@ import ( "testing" "time" + "github.com/go-jose/go-jose/v4/jwt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gopkg.in/go-jose/go-jose.v2/jwt" ) type testClaims struct { @@ -39,9 +39,9 @@ func TestValidator_ValidateToken(t *testing.T) { }{ { name: "it successfully validates a token", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdfQ.-R2K2tZHDrgsEh9JNWcyk4aljtR6gZK0s2anNGlfwz0", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdfQ.ceqLpnraDGaKbQjIlyTFLj8WwwzGhBV3Eo9NDETEXTo", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, expectedClaims: &ValidatedClaims{ @@ -54,9 +54,9 @@ func TestValidator_ValidateToken(t *testing.T) { }, { name: "it successfully validates a token with custom claims", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJzY29wZSI6InJlYWQ6bWVzc2FnZXMifQ.oqtUZQ-Q8un4CPduUBdGVq5gXpQVIFT_QSQjkOXFT5I", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJzY29wZSI6InJlYWQ6bWVzc2FnZXMifQ.Hu9l6uJppZs_-xoj_kQiLIUqaFV14vCLE3nSgx8VFRI", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, customClaims: func() CustomClaims { @@ -75,25 +75,25 @@ func TestValidator_ValidateToken(t *testing.T) { }, { name: "it throws an error when token has a different signing algorithm than the validator", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdfQ.-R2K2tZHDrgsEh9JNWcyk4aljtR6gZK0s2anNGlfwz0", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdfQ.ceqLpnraDGaKbQjIlyTFLj8WwwzGhBV3Eo9NDETEXTo", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: RS256, - expectedError: errors.New(`signing method is invalid: expected "RS256" signing algorithm but token specified "HS256"`), + expectedError: errors.New(`could not parse the token: go-jose/go-jose: unexpected signature algorithm "HS256"; expected ["RS256"]`), }, { name: "it throws an error when it cannot parse the token", token: "", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, expectedError: errors.New("could not parse the token: go-jose/go-jose: compact JWS format must have three parts"), }, { name: "it throws an error when it fails to fetch the keys from the key func", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdfQ.-R2K2tZHDrgsEh9JNWcyk4aljtR6gZK0s2anNGlfwz0", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdfQ.ceqLpnraDGaKbQjIlyTFLj8WwwzGhBV3Eo9NDETEXTo", keyFunc: func(context.Context) (interface{}, error) { return nil, errors.New("key func error message") }, @@ -104,25 +104,25 @@ func TestValidator_ValidateToken(t *testing.T) { name: "it throws an error when it fails to deserialize the claims because the signature is invalid", token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdfQ.vR2K2tZHDrgsEh9zNWcyk4aljtR6gZK0s2anNGlfwz0", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, expectedError: errors.New("failed to deserialize token claims: could not get token claims: go-jose/go-jose: error in cryptographic primitive"), }, { name: "it throws an error when it fails to validate the registered claims", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIn0.VoIwDVmb--26wGrv93NmjNZYa4nrzjLw4JANgEjPI28", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIn0.U2heyMGWbMmhJvfYvXVPe1vK4TlNTiRKekU1EeTEN98", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, expectedError: errors.New("expected claims not validated: go-jose/go-jose/jwt: validation failed, invalid audience claim (aud)"), }, { name: "it throws an error when it fails to validate the custom claims", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJzY29wZSI6InJlYWQ6bWVzc2FnZXMifQ.oqtUZQ-Q8un4CPduUBdGVq5gXpQVIFT_QSQjkOXFT5I", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJzY29wZSI6InJlYWQ6bWVzc2FnZXMifQ.Hu9l6uJppZs_-xoj_kQiLIUqaFV14vCLE3nSgx8VFRI", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, customClaims: func() CustomClaims { @@ -134,9 +134,9 @@ func TestValidator_ValidateToken(t *testing.T) { }, { name: "it successfully validates a token even if customClaims() returns nil", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJzY29wZSI6InJlYWQ6bWVzc2FnZXMifQ.oqtUZQ-Q8un4CPduUBdGVq5gXpQVIFT_QSQjkOXFT5I", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJzY29wZSI6InJlYWQ6bWVzc2FnZXMifQ.Hu9l6uJppZs_-xoj_kQiLIUqaFV14vCLE3nSgx8VFRI", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, customClaims: func() CustomClaims { @@ -153,9 +153,9 @@ func TestValidator_ValidateToken(t *testing.T) { }, { name: "it successfully validates a token with exp, nbf and iat", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjE2NjY5Mzc2ODYsIm5iZiI6MTY2NjkzOTAwMCwiZXhwIjo5NjY3OTM3Njg2fQ.FKZogkm08gTfYfPU6eYu7OHCjJKnKGLiC0IfoIOPEhs", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjE2NjY5Mzc2ODYsIm5iZiI6MTY2NjkzOTAwMCwiZXhwIjo5NjY3OTM3Njg2fQ.F57edUPU8AEkIbLV8bLw1mw4RtKh6MtuPzoQQqin9kE", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, expectedClaims: &ValidatedClaims{ @@ -171,36 +171,36 @@ func TestValidator_ValidateToken(t *testing.T) { }, { name: "it throws an error when token is not valid yet", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjE2NjY5Mzc2ODYsIm5iZiI6OTY2NjkzOTAwMCwiZXhwIjoxNjY3OTM3Njg2fQ.yUizJ-zK_33tv1qBVvDKO0RuCWtvJ02UQKs8gBadgGY", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjE2NjY5Mzc2ODYsIm5iZiI6OTY2NjkzOTAwMCwiZXhwIjoxNjY3OTM3Njg2fQ.E8mqR42CRqEBcG9YzBVb8SGmitcU0sAMDbmG_ueM0EU", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, expectedError: fmt.Errorf("expected claims not validated: %s", jwt.ErrNotValidYet), }, { name: "it throws an error when token is expired", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjE2NjY5Mzc2ODYsIm5iZiI6MTY2NjkzOTAwMCwiZXhwIjo2Njc5Mzc2ODZ9.SKvz82VOXRi_sjvZWIsPG9vSWAXKKgVS4DkGZcwFKL8", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjE2NjY5Mzc2ODYsIm5iZiI6MTY2NjkzOTAwMCwiZXhwIjo2Njc5Mzc2ODZ9.iCJyAzGH5WXq8ffK8kEBumpilEqDHdB4V7X0nN4ppl0", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, expectedError: fmt.Errorf("expected claims not validated: %s", jwt.ErrExpired), }, { name: "it throws an error when token is issued in the future", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjkxNjY2OTM3Njg2LCJuYmYiOjE2NjY5MzkwMDAsImV4cCI6ODY2NzkzNzY4Nn0.ieFV7XNJxiJyw8ARq9yHw-01Oi02e3P2skZO10ypxL8", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjkxNjY2OTM3Njg2LCJuYmYiOjE2NjY5MzkwMDAsImV4cCI6ODY2NzkzNzY4Nn0.USKHRD2wUC5UuYLSL-nUJWs06emOxzX2M6Rv1OzxiM4", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, expectedError: fmt.Errorf("expected claims not validated: %s", jwt.ErrIssuedInTheFuture), }, { name: "it throws an error when token issuer is invalid", - token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2hhY2tlZC1qd3QtbWlkZGxld2FyZS5ldS5hdXRoMC5jb20vIiwic3ViIjoiMTIzNDU2Nzg5MCIsImF1ZCI6WyJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLWFwaS8iXSwiaWF0Ijo5MTY2NjkzNzY4NiwibmJmIjoxNjY2OTM5MDAwLCJleHAiOjg2Njc5Mzc2ODZ9.b5gXNrUNfd_jyCWZF-6IPK_UFfvTr9wBQk9_QgRQ8rA", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2hhY2tlZC1qd3QtbWlkZGxld2FyZS5ldS5hdXRoMC5jb20vIiwic3ViIjoiMTIzNDU2Nzg5MCIsImF1ZCI6WyJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLWFwaS8iXSwiaWF0Ijo5MTY2NjkzNzY4NiwibmJmIjoxNjY2OTM5MDAwLCJleHAiOjg2Njc5Mzc2ODZ9.n-p1CVU0b5FwUIZr7nwl6CfpUq6GKmzBBaFVIGOT6w8", keyFunc: func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil }, algorithm: HS256, expectedError: fmt.Errorf("expected claims not validated: %s", jwt.ErrInvalidIssuer), @@ -234,7 +234,227 @@ func TestValidator_ValidateToken(t *testing.T) { } } -func TestNewValidator(t *testing.T) { +func TestNewValidator_ValidateToken(t *testing.T) { + const ( + issuer = "https://go-jwt-middleware.eu.auth0.com/" + audience = "https://go-jwt-middleware-api/" + subject = "1234567890" + issuerB = "https://go-jwt-middleware.us.auth0.com/" + audienceB = "https://go-jwt-middleware-api-b/" + ) + + testCases := []struct { + name string + token string + keyFunc func(context.Context) (interface{}, error) + algorithm SignatureAlgorithm + customClaims func() CustomClaims + expectedError error + expectedClaims *ValidatedClaims + }{ + { + name: "it successfully validates a token", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdfQ.ceqLpnraDGaKbQjIlyTFLj8WwwzGhBV3Eo9NDETEXTo", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + expectedClaims: &ValidatedClaims{ + RegisteredClaims: RegisteredClaims{ + Issuer: issuer, + Subject: subject, + Audience: []string{audience}, + }, + }, + }, + { + name: "it successfully validates a token with custom claims", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJzY29wZSI6InJlYWQ6bWVzc2FnZXMifQ.Hu9l6uJppZs_-xoj_kQiLIUqaFV14vCLE3nSgx8VFRI", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + customClaims: func() CustomClaims { + return &testClaims{} + }, + expectedClaims: &ValidatedClaims{ + RegisteredClaims: RegisteredClaims{ + Issuer: issuer, + Subject: subject, + Audience: []string{audience}, + }, + CustomClaims: &testClaims{ + Scope: "read:messages", + }, + }, + }, + { + name: "it throws an error when token has a different signing algorithm than the validator", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdfQ.ceqLpnraDGaKbQjIlyTFLj8WwwzGhBV3Eo9NDETEXTo", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: RS256, + expectedError: errors.New(`could not parse the token: go-jose/go-jose: unexpected signature algorithm "HS256"; expected ["RS256"]`), + }, + { + name: "it throws an error when it cannot parse the token", + token: "", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + expectedError: errors.New("could not parse the token: go-jose/go-jose: compact JWS format must have three parts"), + }, + { + name: "it throws an error when it fails to fetch the keys from the key func", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdfQ.ceqLpnraDGaKbQjIlyTFLj8WwwzGhBV3Eo9NDETEXTo", + keyFunc: func(context.Context) (interface{}, error) { + return nil, errors.New("key func error message") + }, + algorithm: HS256, + expectedError: errors.New("failed to deserialize token claims: error getting the keys from the key func: key func error message"), + }, + { + name: "it throws an error when it fails to deserialize the claims because the signature is invalid", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdfQ.vR2K2tZHDrgsEh9zNWcyk4aljtR6gZK0s2anNGlfwz0", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + expectedError: errors.New("failed to deserialize token claims: could not get token claims: go-jose/go-jose: error in cryptographic primitive"), + }, + { + name: "it throws an error when it fails to validate the registered claims", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIn0.U2heyMGWbMmhJvfYvXVPe1vK4TlNTiRKekU1EeTEN98", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + expectedError: errors.New("go-jose/go-jose/jwt: validation failed, invalid audience claim (aud)"), + }, + { + name: "it throws an error when it fails to validate the custom claims", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJzY29wZSI6InJlYWQ6bWVzc2FnZXMifQ.Hu9l6uJppZs_-xoj_kQiLIUqaFV14vCLE3nSgx8VFRI", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + customClaims: func() CustomClaims { + return &testClaims{ + ReturnError: errors.New("custom claims error message"), + } + }, + expectedError: errors.New("custom claims not validated: custom claims error message"), + }, + { + name: "it successfully validates a token even if customClaims() returns nil", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJzY29wZSI6InJlYWQ6bWVzc2FnZXMifQ.Hu9l6uJppZs_-xoj_kQiLIUqaFV14vCLE3nSgx8VFRI", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + customClaims: func() CustomClaims { + return nil + }, + expectedClaims: &ValidatedClaims{ + RegisteredClaims: RegisteredClaims{ + Issuer: issuer, + Subject: subject, + Audience: []string{audience}, + }, + CustomClaims: nil, + }, + }, + { + name: "it successfully validates a token with exp, nbf and iat", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjE2NjY5Mzc2ODYsIm5iZiI6MTY2NjkzOTAwMCwiZXhwIjo5NjY3OTM3Njg2fQ.F57edUPU8AEkIbLV8bLw1mw4RtKh6MtuPzoQQqin9kE", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + expectedClaims: &ValidatedClaims{ + RegisteredClaims: RegisteredClaims{ + Issuer: issuer, + Subject: subject, + Audience: []string{audience}, + Expiry: 9667937686, + NotBefore: 1666939000, + IssuedAt: 1666937686, + }, + }, + }, + { + name: "it throws an error when token is not valid yet", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjE2NjY5Mzc2ODYsIm5iZiI6OTY2NjkzOTAwMCwiZXhwIjoxNjY3OTM3Njg2fQ.E8mqR42CRqEBcG9YzBVb8SGmitcU0sAMDbmG_ueM0EU", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + expectedError: fmt.Errorf("expected claims not validated: %s", jwt.ErrNotValidYet), + }, + { + name: "it throws an error when token is expired", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjE2NjY5Mzc2ODYsIm5iZiI6MTY2NjkzOTAwMCwiZXhwIjo2Njc5Mzc2ODZ9.iCJyAzGH5WXq8ffK8kEBumpilEqDHdB4V7X0nN4ppl0", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + expectedError: fmt.Errorf("expected claims not validated: %s", jwt.ErrExpired), + }, + { + name: "it throws an error when token is issued in the future", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjpbImh0dHBzOi8vZ28tand0LW1pZGRsZXdhcmUtYXBpLyJdLCJpYXQiOjkxNjY2OTM3Njg2LCJuYmYiOjE2NjY5MzkwMDAsImV4cCI6ODY2NzkzNzY4Nn0.USKHRD2wUC5UuYLSL-nUJWs06emOxzX2M6Rv1OzxiM4", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + expectedError: fmt.Errorf("expected claims not validated: %s", jwt.ErrIssuedInTheFuture), + }, + { + name: "it throws an error when token issuer is invalid", + token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2hhY2tlZC1qd3QtbWlkZGxld2FyZS5ldS5hdXRoMC5jb20vIiwic3ViIjoiMTIzNDU2Nzg5MCIsImF1ZCI6WyJodHRwczovL2dvLWp3dC1taWRkbGV3YXJlLWFwaS8iXSwiaWF0Ijo5MTY2NjkzNzY4NiwibmJmIjoxNjY2OTM5MDAwLCJleHAiOjg2Njc5Mzc2ODZ9.n-p1CVU0b5FwUIZr7nwl6CfpUq6GKmzBBaFVIGOT6w8", + keyFunc: func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + }, + algorithm: HS256, + expectedError: fmt.Errorf("expected claims not validated: %s", jwt.ErrInvalidIssuer), + }, + } + + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + + validator, err := NewValidator( + testCase.keyFunc, + testCase.algorithm, + WithCustomClaims(testCase.customClaims), + WithAllowedClockSkew(time.Second), + WithExpectedClaims(jwt.Expected{ + Issuer: issuer, + AnyAudience: []string{audience, "another-audience"}, + }, jwt.Expected{ + Issuer: issuerB, + AnyAudience: []string{audienceB, "another-audienceb"}, + }), + ) + require.NoError(t, err) + + tokenClaims, err := validator.ValidateToken(context.Background(), testCase.token) + if testCase.expectedError != nil { + assert.ErrorContains(t, err, testCase.expectedError.Error()) + assert.Nil(t, tokenClaims) + } else { + require.NoError(t, err) + assert.Exactly(t, testCase.expectedClaims, tokenClaims) + } + }) + } +} + +func TestNew(t *testing.T) { const ( issuer = "https://go-jwt-middleware.eu.auth0.com/" audience = "https://go-jwt-middleware-api/" @@ -242,7 +462,7 @@ func TestNewValidator(t *testing.T) { ) var keyFunc = func(context.Context) (interface{}, error) { - return []byte("secret"), nil + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil } t.Run("it throws an error when the keyFunc is nil", func(t *testing.T) { @@ -260,12 +480,12 @@ func TestNewValidator(t *testing.T) { assert.EqualError(t, err, "unsupported signature algorithm") }) - t.Run("it throws an error when the issuerURL is empty", func(t *testing.T) { + t.Run("it throws an error when the issuerURL is empty and no expectedClaims option", func(t *testing.T) { _, err := New(keyFunc, algorithm, "", []string{audience}) assert.EqualError(t, err, "issuer url is required but was empty") }) - t.Run("it throws an error when the audience is nil", func(t *testing.T) { + t.Run("it throws an error when the audience is nil if no expectedClaims option included", func(t *testing.T) { _, err := New(keyFunc, algorithm, issuer, nil) assert.EqualError(t, err, "audience is required but was empty") }) @@ -274,4 +494,81 @@ func TestNewValidator(t *testing.T) { _, err := New(keyFunc, algorithm, issuer, []string{}) assert.EqualError(t, err, "audience is required but was empty") }) + + t.Run("it throws an error when the issuerURL is empty and an expectedClaims option with only an audience", func(t *testing.T) { + _, err := New(keyFunc, algorithm, "", []string{}, WithExpectedClaims(jwt.Expected{AnyAudience: []string{audience}})) + assert.EqualError(t, err, "issuer url 0 is required but was empty") + }) + + t.Run("it throws an error when the audience is empty and the expectedClaims are missing an audience", func(t *testing.T) { + _, err := New(keyFunc, algorithm, issuer, []string{}, WithExpectedClaims(jwt.Expected{Issuer: issuer})) + assert.EqualError(t, err, "audience 0 is required but was empty") + }) + + t.Run("it throws no error when the issuerURL is empty but expectedClaims option included", func(t *testing.T) { + _, err := New(keyFunc, algorithm, "", []string{audience}, WithExpectedClaims(jwt.Expected{Issuer: issuer, AnyAudience: []string{audience}})) + assert.NoError(t, err, "no error was expected") + }) + + t.Run("it throws no error when the audience is nil but expectedClaims option included", func(t *testing.T) { + _, err := New(keyFunc, algorithm, issuer, nil, WithExpectedClaims(jwt.Expected{Issuer: issuer, AnyAudience: []string{audience}})) + assert.NoError(t, err, "no error was expected") + }) +} + +func TestNewValidator(t *testing.T) { + const ( + issuer = "https://go-jwt-middleware.eu.auth0.com/" + audience = "https://go-jwt-middleware-api/" + algorithm = HS256 + ) + + var keyFunc = func(context.Context) (interface{}, error) { + return []byte("abcdefghijklmnopqrstuvwxyz012345"), nil + } + + t.Run("it throws an error when the keyFunc is nil", func(t *testing.T) { + _, err := NewValidator(nil, algorithm) + assert.EqualError(t, err, "keyFunc is required but was nil") + }) + + t.Run("it throws an error when the signature algorithm is empty", func(t *testing.T) { + _, err := NewValidator(keyFunc, "") + assert.EqualError(t, err, "unsupported signature algorithm") + }) + + t.Run("it throws an error when the signature algorithm is unsupported", func(t *testing.T) { + _, err := NewValidator(keyFunc, "none") + assert.EqualError(t, err, "unsupported signature algorithm") + }) + + t.Run("it throws an error when there are no expected claims", func(t *testing.T) { + _, err := NewValidator(keyFunc, algorithm) + assert.EqualError(t, err, "expected claims but none provided") + }) + + t.Run("it throws an error when expectedClaims option with only an audience", func(t *testing.T) { + _, err := NewValidator(keyFunc, algorithm, WithExpectedClaims(jwt.Expected{AnyAudience: []string{audience}})) + assert.EqualError(t, err, "issuer url 0 is required but was empty") + }) + + t.Run("it throws an error when expectedClaims option with only an audience in the second jwt.Expected", func(t *testing.T) { + _, err := NewValidator(keyFunc, algorithm, WithExpectedClaims(jwt.Expected{Issuer: issuer, AnyAudience: []string{audience}}, jwt.Expected{AnyAudience: []string{audience}})) + assert.EqualError(t, err, "issuer url 1 is required but was empty") + }) + + t.Run("it throws an error when the audience is empty and the expectedClaims are missing an audience", func(t *testing.T) { + _, err := NewValidator(keyFunc, algorithm, WithExpectedClaims(jwt.Expected{Issuer: issuer})) + assert.EqualError(t, err, "audience 0 is required but was empty") + }) + + t.Run("it throws an error when the audience is empty and the expectedClaims are missing an audience in the second jwt.Expected", func(t *testing.T) { + _, err := NewValidator(keyFunc, algorithm, WithExpectedClaims(jwt.Expected{Issuer: issuer, AnyAudience: []string{audience}}, jwt.Expected{Issuer: issuer})) + assert.EqualError(t, err, "audience 1 is required but was empty") + }) + + t.Run("it throws no error when input is correct", func(t *testing.T) { + _, err := NewValidator(keyFunc, algorithm, WithExpectedClaims(jwt.Expected{Issuer: issuer, AnyAudience: []string{audience}})) + assert.NoError(t, err, "no error was expected") + }) } From 18fa23a0b5b8e814f9803d36637b5ce3d882a92b Mon Sep 17 00:00:00 2001 From: Chris Moran Date: Tue, 2 Sep 2025 05:55:49 -0400 Subject: [PATCH 2/2] chore: sync with upstream --- .gitignore | 5 ++- examples/echo-example/go.mod | 11 +++--- examples/echo-example/go.sum | 40 +++++-------------- examples/gin-example/go.mod | 20 +++++----- examples/gin-example/go.sum | 64 +++++++++++------------------- examples/http-example/go.mod | 2 +- examples/http-example/go.sum | 4 +- examples/http-jwks-example/go.mod | 2 +- examples/http-jwks-example/go.sum | 4 +- examples/iris-example/go.mod | 11 +++--- examples/iris-example/go.sum | 66 +++++++------------------------ go.mod | 2 +- go.sum | 4 +- 13 files changed, 81 insertions(+), 154 deletions(-) diff --git a/.gitignore b/.gitignore index 2360a8e4..2d423d8b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +#ignore all by default +* # Binaries for programs and plugins *.exe *.exe~ @@ -13,4 +15,5 @@ *.out # Dependency directories -vendor/ \ No newline at end of file +vendor/ +!*/ diff --git a/examples/echo-example/go.mod b/examples/echo-example/go.mod index 9f3b1854..738940a0 100644 --- a/examples/echo-example/go.mod +++ b/examples/echo-example/go.mod @@ -12,15 +12,14 @@ require ( replace github.com/auth0/go-jwt-middleware/v2 => ./../../ require ( - github.com/go-jose/go-jose/v4 v4.0.4 // indirect + github.com/go-jose/go-jose/v4 v4.0.5 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - golang.org/x/crypto v0.35.0 // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect - gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect ) diff --git a/examples/echo-example/go.sum b/examples/echo-example/go.sum index b3937cce..ccee128a 100644 --- a/examples/echo-example/go.sum +++ b/examples/echo-example/go.sum @@ -1,55 +1,35 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/labstack/echo/v4 v4.11.2 h1:T+cTLQxWCDfqDEoydYm5kCobjmHwOwcv4OJAPHilmdE= -github.com/labstack/echo/v4 v4.11.2/go.mod h1:UcGuQ8V6ZNRmSweBIJkPvGfwCMIlFmiqrPqiEBfPYws= github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs= -gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/gin-example/go.mod b/examples/gin-example/go.mod index 975c0138..4fd26682 100644 --- a/examples/gin-example/go.mod +++ b/examples/gin-example/go.mod @@ -5,36 +5,36 @@ go 1.23.0 require ( github.com/auth0/go-jwt-middleware/v2 v2.2.2 github.com/gin-gonic/gin v1.10.0 - github.com/go-jose/go-jose/v4 v4.0.4 + github.com/go-jose/go-jose/v4 v4.0.5 ) replace github.com/auth0/go-jwt-middleware/v2 => ./../../ require ( - github.com/bytedance/sonic v1.10.2 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect - github.com/chenzhuoyu/iasm v0.9.1 // indirect + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.15.5 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.1.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect - golang.org/x/arch v0.5.0 // indirect + golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.35.0 // indirect golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.30.0 // indirect golang.org/x/text v0.22.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect - gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/gin-example/go.sum b/examples/gin-example/go.sum index 515e6480..18f2e028 100644 --- a/examples/gin-example/go.sum +++ b/examples/gin-example/go.sum @@ -1,36 +1,30 @@ -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= -github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE= -github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= -github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= -github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= -github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0= -github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= -github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= @@ -39,15 +33,11 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -55,49 +45,43 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= -github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= -github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.5.0 h1:jpGode6huXQxcskEIpOCvrU+tzo81b6+oFLUYXWtH/Y= -golang.org/x/arch v0.5.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs= -gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/http-example/go.mod b/examples/http-example/go.mod index c1f43a72..b67e1f44 100644 --- a/examples/http-example/go.mod +++ b/examples/http-example/go.mod @@ -4,7 +4,7 @@ go 1.23.0 require ( github.com/auth0/go-jwt-middleware/v2 v2.2.2 - github.com/go-jose/go-jose/v4 v4.0.4 + github.com/go-jose/go-jose/v4 v4.0.5 ) replace github.com/auth0/go-jwt-middleware/v2 => ./../../ diff --git a/examples/http-example/go.sum b/examples/http-example/go.sum index 45110433..ee80d6ec 100644 --- a/examples/http-example/go.sum +++ b/examples/http-example/go.sum @@ -1,5 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -8,7 +10,5 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= -gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs= -gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/http-jwks-example/go.mod b/examples/http-jwks-example/go.mod index 7b5c37d4..735bb95e 100644 --- a/examples/http-jwks-example/go.mod +++ b/examples/http-jwks-example/go.mod @@ -4,7 +4,7 @@ go 1.23.0 require ( github.com/auth0/go-jwt-middleware/v2 v2.2.2 - github.com/go-jose/go-jose/v4 v4.0.4 + github.com/go-jose/go-jose/v4 v4.0.5 ) replace github.com/auth0/go-jwt-middleware/v2 => ./../../ diff --git a/examples/http-jwks-example/go.sum b/examples/http-jwks-example/go.sum index 3cf917eb..6d70e8c9 100644 --- a/examples/http-jwks-example/go.sum +++ b/examples/http-jwks-example/go.sum @@ -1,5 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -10,7 +12,5 @@ golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs= -gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/iris-example/go.mod b/examples/iris-example/go.mod index ea4963f8..ec7e2f88 100644 --- a/examples/iris-example/go.mod +++ b/examples/iris-example/go.mod @@ -19,7 +19,7 @@ require ( github.com/aymerick/douceur v0.2.0 // indirect github.com/fatih/structs v1.1.0 // indirect github.com/flosch/pongo2/v4 v4.0.2 // indirect - github.com/go-jose/go-jose/v4 v4.0.4 // indirect + github.com/go-jose/go-jose/v4 v4.0.5 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/gomarkdown/markdown v0.0.0-20250207164621-7a1f277a159e // indirect github.com/google/uuid v1.6.0 // indirect @@ -44,14 +44,13 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/yosssi/ace v0.0.5 // indirect - golang.org/x/crypto v0.35.0 // indirect + golang.org/x/crypto v0.36.0 // indirect golang.org/x/exp v0.0.0-20250228200357-dead58393ab7 // indirect - golang.org/x/net v0.33.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/protobuf v1.33.0 // indirect - gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/iris-example/go.sum b/examples/iris-example/go.sum index f8d74f54..b783b434 100644 --- a/examples/iris-example/go.sum +++ b/examples/iris-example/go.sum @@ -1,5 +1,5 @@ -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME= @@ -8,16 +8,10 @@ github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 h1:KkH3I3sJuOLP3TjA/dfr4NAY8bghDwnXiU7cTKxQqo0= -github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= github.com/Shopify/goreferrer v0.0.0-20240724165105-aceaa0259138 h1:gjbp60h8IZQbN/TpDaYJedWbbD1h1aDPEwWnYWaDaUY= github.com/Shopify/goreferrer v0.0.0-20240724165105-aceaa0259138/go.mod h1:NYezi6wtnJtBm5btoprXc5SvAdqH0XTXWnUup0MptAI= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= -github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= @@ -31,29 +25,26 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20240729212818-a2a9c4f76ef5 h1:8QWUW69MXlNdZXnDnD9vEQ1BL8/mm1FTiSesKKHYivk= -github.com/gomarkdown/markdown v0.0.0-20240729212818-a2a9c4f76ef5/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/gomarkdown/markdown v0.0.0-20250207164621-7a1f277a159e h1:ESHlT0RVZphh4JGBz49I5R6nTdC8Qyc08vU25GQHzzQ= github.com/gomarkdown/markdown v0.0.0-20250207164621-7a1f277a159e/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= -github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/iris-contrib/httpexpect/v2 v2.15.2 h1:T9THsdP1woyAqKHwjkEsbCnMefsAFvk8iJJKokcJ3Go= @@ -62,32 +53,18 @@ github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvP github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/kataras/blocks v0.0.8 h1:MrpVhoFTCR2v1iOOfGng5VJSILKeZZI+7NGfxEh3SUM= -github.com/kataras/blocks v0.0.8/go.mod h1:9Jm5zx6BB+06NwA+OhTbHW1xkMOYxahnqTN5DveZ2Yg= github.com/kataras/blocks v0.0.11 h1:JJdYW0AUaJKLx5kEWs/oRVCvKVXo+6CAAeaVAiJf7wE= github.com/kataras/blocks v0.0.11/go.mod h1:b4UySrJySEOq6drKH9U3bOpMI+dRH148mayYfS3RFb8= -github.com/kataras/golog v0.1.9 h1:vLvSDpP7kihFGKFAvBSofYo7qZNULYSHOH2D7rPTKJk= -github.com/kataras/golog v0.1.9/go.mod h1:jlpk/bOaYCyqDqH18pgDHdaJab72yBE6i0O3s30hpWY= -github.com/kataras/golog v0.1.11 h1:dGkcCVsIpqiAMWTlebn/ZULHxFvfG4K43LF1cNWSh20= -github.com/kataras/golog v0.1.11/go.mod h1:mAkt1vbPowFUuUGvexyQ5NFW6djEgGyxQBIARJ0AH4A= github.com/kataras/golog v0.1.12 h1:Bu7I/G4ilJlbfzjmU39O9N+2uO1pBcMK045fzZ4ytNg= github.com/kataras/golog v0.1.12/go.mod h1:wrGSbOiBqbQSQznleVNX4epWM8rl9SJ/rmEacl0yqy4= -github.com/kataras/iris/v12 v12.2.7 h1:C9KWZmZT5pB5f2ot1XYWDBdi5XeTz0CGweHRXCDARZg= -github.com/kataras/iris/v12 v12.2.7/go.mod h1:mD76k/tIBFy8pHTFIgUPrVrkI4lTKvFbIcfbStJSBnA= github.com/kataras/iris/v12 v12.2.11 h1:sGgo43rMPfzDft8rjVhPs6L3qDJy3TbBrMD/zGL1pzk= github.com/kataras/iris/v12 v12.2.11/go.mod h1:uMAeX8OqG9vqdhyrIPv8Lajo/wXTtAF43wchP9WHt2w= -github.com/kataras/pio v0.0.12 h1:o52SfVYauS3J5X08fNjlGS5arXHjW/ItLkyLcKjoH6w= -github.com/kataras/pio v0.0.12/go.mod h1:ODK/8XBhhQ5WqrAhKy+9lTPS7sBf6O3KcLhc9klfRcY= github.com/kataras/pio v0.0.13 h1:x0rXVX0fviDTXOOLOmr4MUxOabu1InVSTu5itF8CXCM= github.com/kataras/pio v0.0.13/go.mod h1:k3HNuSw+eJ8Pm2lA4lRhg3DiCjVgHlP8hmXApSej3oM= github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= -github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= -github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -101,8 +78,6 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= -github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= @@ -127,26 +102,15 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tdewolff/minify/v2 v2.12.9 h1:dvn5MtmuQ/DFMwqf5j8QhEVpPX6fi3WGImhv8RUB4zA= -github.com/tdewolff/minify/v2 v2.12.9/go.mod h1:qOqdlDfL+7v0/fyymB+OP497nIxJYSvX4MQWA8OoiXU= -github.com/tdewolff/minify/v2 v2.20.19 h1:tX0SR0LUrIqGoLjXnkIzRSIbKJ7PaNnSENLD4CyH6Xo= -github.com/tdewolff/minify/v2 v2.20.19/go.mod h1:ulkFoeAVWMLEyjuDz1ZIWOA31g5aWOawCFRp9R/MudM= github.com/tdewolff/minify/v2 v2.20.37 h1:Q97cx4STXCh1dlWDlNHZniE8BJ2EBL0+2b0n92BJQhw= github.com/tdewolff/minify/v2 v2.20.37/go.mod h1:L1VYef/jwKw6Wwyk5A+T0mBjjn3mMPgmjjA688RNsxU= -github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvFMA= -github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM= -github.com/tdewolff/parse/v2 v2.7.12 h1:tgavkHc2ZDEQVKy1oWxwIyh5bP4F5fEh/JmBwPP/3LQ= -github.com/tdewolff/parse/v2 v2.7.12/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= github.com/tdewolff/parse/v2 v2.7.20 h1:Y33JmRLjyGhX5JRvYh+CO6Sk6pGMw3iO5eKGhUhx8JE= github.com/tdewolff/parse/v2 v2.7.20/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= -github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0= -github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo= +github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/vmihailenco/msgpack/v5 v5.4.0 h1:hRM0digJwyR6vll33NNAwCFguy5JuBD6jxDmQP3l608= -github.com/vmihailenco/msgpack/v5 v5.4.0/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= @@ -157,6 +121,7 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= @@ -171,10 +136,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20250228200357-dead58393ab7 h1:aWwlzYV971S4BXRS9AmqwDLAD85ouC6X+pocatKY58c= golang.org/x/exp v0.0.0-20250228200357-dead58393ab7/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= @@ -184,6 +146,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -195,14 +159,14 @@ golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -216,8 +180,6 @@ google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHh gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs= -gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/go.mod b/go.mod index 05ab4f15..f6995e77 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/auth0/go-jwt-middleware/v2 go 1.23.0 require ( - github.com/go-jose/go-jose/v4 v4.0.4 + github.com/go-jose/go-jose/v4 v4.0.5 github.com/google/go-cmp v0.7.0 github.com/stretchr/testify v1.10.0 golang.org/x/sync v0.11.0 diff --git a/go.sum b/go.sum index 044dd052..61d944eb 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -12,7 +14,5 @@ golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs= -gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=