diff --git a/README.md b/README.md index 97a96eca..8619985f 100644 --- a/README.md +++ b/README.md @@ -107,13 +107,13 @@ There are a lot of backward incompatible changes: ### Installation ```shell -go get github.com/Nerzal/gocloak/v9 +go get github.com/Nerzal/10 ``` ### Importing ```go - import "github.com/Nerzal/gocloak/v9" + import "github.com/Nerzal/gocloak/v10" ``` ### Create New User diff --git a/client.go b/client.go index 1a0637cc..71c0319f 100644 --- a/client.go +++ b/client.go @@ -11,13 +11,13 @@ import ( "sync" "time" - "github.com/dgrijalva/jwt-go/v4" "github.com/go-resty/resty/v2" + "github.com/golang-jwt/jwt/v4" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/segmentio/ksuid" - "github.com/Nerzal/gocloak/v9/pkg/jwx" + "github.com/Nerzal/gocloak/v10/pkg/jwx" ) type gocloak struct { @@ -380,7 +380,7 @@ func (client *gocloak) RetrospectToken(ctx context.Context, accessToken, clientI } // DecodeAccessToken decodes the accessToken -func (client *gocloak) DecodeAccessToken(ctx context.Context, accessToken, realm, expectedAudience string) (*jwt.Token, *jwt.MapClaims, error) { +func (client *gocloak) DecodeAccessToken(ctx context.Context, accessToken, realm string) (*jwt.Token, *jwt.MapClaims, error) { const errMessage = "could not decode access token" accessToken = strings.Replace(accessToken, "Bearer ", "", 1) @@ -401,11 +401,11 @@ func (client *gocloak) DecodeAccessToken(ctx context.Context, accessToken, realm return nil, nil, errors.Wrap(errors.New("cannot find a key to decode the token"), errMessage) } - return jwx.DecodeAccessToken(accessToken, usedKey.E, usedKey.N, expectedAudience) + return jwx.DecodeAccessToken(accessToken, usedKey.E, usedKey.N) } // DecodeAccessTokenCustomClaims decodes the accessToken and writes claims into the given claims -func (client *gocloak) DecodeAccessTokenCustomClaims(ctx context.Context, accessToken, realm, expectedAudience string, claims jwt.Claims) (*jwt.Token, error) { +func (client *gocloak) DecodeAccessTokenCustomClaims(ctx context.Context, accessToken, realm string, claims jwt.Claims) (*jwt.Token, error) { const errMessage = "could not decode access token with custom claims" accessToken = strings.Replace(accessToken, "Bearer ", "", 1) @@ -426,7 +426,7 @@ func (client *gocloak) DecodeAccessTokenCustomClaims(ctx context.Context, access return nil, errors.Wrap(errors.New("cannot find a key to decode the token"), errMessage) } - return jwx.DecodeAccessTokenCustomClaims(accessToken, usedKey.E, usedKey.N, claims, expectedAudience) + return jwx.DecodeAccessTokenCustomClaims(accessToken, usedKey.E, usedKey.N, claims) } func (client *gocloak) GetToken(ctx context.Context, realm string, options TokenOptions) (*JWT, error) { @@ -552,9 +552,9 @@ func (client *gocloak) LoginClientSignedJWT( realm string, key interface{}, signedMethod jwt.SigningMethod, - expiresAt *jwt.Time, + expiresAt *jwt.NumericDate, ) (*JWT, error) { - claims := jwt.StandardClaims{ + claims := jwt.RegisteredClaims{ ExpiresAt: expiresAt, Issuer: clientID, Subject: clientID, diff --git a/client_benchmark_test.go b/client_benchmark_test.go index 0a5711d6..c5265097 100644 --- a/client_benchmark_test.go +++ b/client_benchmark_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - "github.com/Nerzal/gocloak/v9" + "github.com/Nerzal/gocloak/v10" "github.com/stretchr/testify/assert" ) diff --git a/client_test.go b/client_test.go index 83ab041c..347a4155 100644 --- a/client_test.go +++ b/client_test.go @@ -21,12 +21,12 @@ import ( "testing" "time" - "github.com/dgrijalva/jwt-go/v4" "github.com/go-resty/resty/v2" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/require" "golang.org/x/crypto/pkcs12" - "github.com/Nerzal/gocloak/v9" + "github.com/Nerzal/gocloak/v10" ) type configAdmin struct { @@ -872,7 +872,6 @@ func Test_DecodeAccessToken(t *testing.T) { context.Background(), token.AccessToken, cfg.GoCloak.Realm, - "", ) require.NoError(t, err) t.Log(resultToken) @@ -889,7 +888,6 @@ func Test_DecodeAccessTokenCustomClaims(t *testing.T) { context.Background(), token.AccessToken, cfg.GoCloak.Realm, - "", claims, ) require.NoError(t, err) @@ -994,9 +992,7 @@ func Test_LoginSignedJWT(t *testing.T) { cfg.GoCloak.Realm, rsaKey, jwt.SigningMethodRS256, - &jwt.Time{ - Time: time.Now().Add(time.Hour), - }, + &jwt.NumericDate{}, ) require.NoError(t, err, "Login failed") } diff --git a/go.mod b/go.mod index b984b1c6..02cbd14c 100644 --- a/go.mod +++ b/go.mod @@ -1,15 +1,15 @@ -module github.com/Nerzal/gocloak/v9 +module github.com/Nerzal/gocloak/v10 go 1.15 require ( - github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 - github.com/go-resty/resty/v2 v2.3.0 + github.com/go-resty/resty/v2 v2.6.0 + github.com/golang-jwt/jwt/v4 v4.1.0 github.com/opentracing/opentracing-go v1.2.0 github.com/pkg/errors v0.9.1 - github.com/segmentio/ksuid v1.0.3 - github.com/stretchr/testify v1.6.1 - golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a - golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect - gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect + github.com/segmentio/ksuid v1.0.4 + github.com/stretchr/testify v1.7.0 + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 + golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index 961d5169..1a7b4fd5 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,11 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU= -github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= github.com/go-resty/resty/v2 v2.3.0 h1:JOOeAvjSlapTT92p8xiS19Zxev1neGikoHsXJeOq8So= github.com/go-resty/resty/v2 v2.3.0/go.mod h1:UpN9CgLZNsv4e9XG50UU8xdI0F43UQ4HmxLBDwaroHU= +github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4= +github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q= +github.com/golang-jwt/jwt/v4 v4.1.0 h1:XUgk2Ex5veyVFVeLm0xhusUTQybEbexJXrvPNOKkSY0= +github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -12,26 +14,45 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/segmentio/ksuid v1.0.3 h1:FoResxvleQwYiPAVKe1tMUlEirodZqlqglIuFsdDntY= github.com/segmentio/ksuid v1.0.3/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= +github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= +github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b h1:eB48h3HiRycXNy8E0Gf5e0hv7YT6Kt14L/D73G1fuwo= +golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/gocloak.go b/gocloak.go index cde307ec..d09bdf9f 100644 --- a/gocloak.go +++ b/gocloak.go @@ -4,8 +4,8 @@ import ( "context" "io" - "github.com/dgrijalva/jwt-go/v4" "github.com/go-resty/resty/v2" + "github.com/golang-jwt/jwt/v4" ) // GoCloak holds all methods a client should fulfill @@ -43,15 +43,15 @@ type GoCloak interface { // LoginClientTokenExchange requests a login on a specified users behalf. Returning a user's tokens. LoginClientTokenExchange(ctx context.Context, clientID, token, clientSecret, realm, targetClient, userID string) (*JWT, error) // LoginClientSignedJWT performs a login with client credentials and signed jwt claims - LoginClientSignedJWT(ctx context.Context, idOfClient, realm string, key interface{}, signedMethod jwt.SigningMethod, expiresAt *jwt.Time) (*JWT, error) + LoginClientSignedJWT(ctx context.Context, idOfClient, realm string, key interface{}, signedMethod jwt.SigningMethod, expiresAt *jwt.NumericDate) (*JWT, error) // LoginAdmin login as admin LoginAdmin(ctx context.Context, username, password, realm string) (*JWT, error) // RefreshToken used to refresh the token RefreshToken(ctx context.Context, refreshToken, clientID, clientSecret, realm string) (*JWT, error) // DecodeAccessToken decodes the accessToken - DecodeAccessToken(ctx context.Context, accessToken, realm, expectedAudience string) (*jwt.Token, *jwt.MapClaims, error) + DecodeAccessToken(ctx context.Context, accessToken, realm string) (*jwt.Token, *jwt.MapClaims, error) // DecodeAccessTokenCustomClaims decodes the accessToken and fills the given claims - DecodeAccessTokenCustomClaims(ctx context.Context, accessToken, realm, expectedAudience string, claims jwt.Claims) (*jwt.Token, error) + DecodeAccessTokenCustomClaims(ctx context.Context, accessToken, realm string, claims jwt.Claims) (*jwt.Token, error) // RetrospectToken calls the openid-connect introspect endpoint RetrospectToken(ctx context.Context, accessToken, clientID, clientSecret, realm string) (*RetrospecTokenResult, error) // GetIssuer calls the issuer endpoint for the given realm diff --git a/model_test.go b/model_test.go index 59300aba..88458df4 100644 --- a/model_test.go +++ b/model_test.go @@ -5,7 +5,7 @@ import ( "errors" "testing" - "github.com/Nerzal/gocloak/v9" + "github.com/Nerzal/gocloak/v10" "github.com/stretchr/testify/assert" ) diff --git a/models.go b/models.go index 0eb0d405..dd10b692 100644 --- a/models.go +++ b/models.go @@ -4,7 +4,7 @@ import ( "encoding/json" "strings" - "github.com/dgrijalva/jwt-go/v4" + "github.com/golang-jwt/jwt/v4" ) // GetQueryParams converts the struct to map[string]string diff --git a/pkg/jwx/jwx.go b/pkg/jwx/jwx.go index 64824fc0..23b8d5f1 100644 --- a/pkg/jwx/jwx.go +++ b/pkg/jwx/jwx.go @@ -10,7 +10,7 @@ import ( "math/big" "strings" - jwt "github.com/dgrijalva/jwt-go/v4" + "github.com/golang-jwt/jwt/v4" "github.com/pkg/errors" ) @@ -75,7 +75,7 @@ func decodePublicKey(e, n *string) (*rsa.PublicKey, error) { } // DecodeAccessToken currently only supports RSA - sorry for that -func DecodeAccessToken(accessToken string, e, n *string, expectedAudience string) (*jwt.Token, *jwt.MapClaims, error) { +func DecodeAccessToken(accessToken string, e, n *string) (*jwt.Token, *jwt.MapClaims, error) { const errMessage = "could not decode accessToken" accessToken = strings.Replace(accessToken, "Bearer ", "", 1) @@ -86,18 +86,13 @@ func DecodeAccessToken(accessToken string, e, n *string, expectedAudience string claims := &jwt.MapClaims{} - audValidation := jwt.WithoutAudienceValidation() - if expectedAudience != "" { - audValidation = jwt.WithAudience(expectedAudience) - } - token2, err := jwt.ParseWithClaims(accessToken, claims, func(token *jwt.Token) (interface{}, error) { // Don't forget to validate the alg is what you expect: if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return rsaPublicKey, nil - }, audValidation) + }) if err != nil { return nil, nil, errors.Wrap(err, errMessage) @@ -107,7 +102,7 @@ func DecodeAccessToken(accessToken string, e, n *string, expectedAudience string } // DecodeAccessTokenCustomClaims currently only supports RSA - sorry for that -func DecodeAccessTokenCustomClaims(accessToken string, e, n *string, customClaims jwt.Claims, expectedAudience string) (*jwt.Token, error) { +func DecodeAccessTokenCustomClaims(accessToken string, e, n *string, customClaims jwt.Claims) (*jwt.Token, error) { const errMessage = "could not decode accessToken with custom claims" accessToken = strings.Replace(accessToken, "Bearer ", "", 1) @@ -116,18 +111,13 @@ func DecodeAccessTokenCustomClaims(accessToken string, e, n *string, customClaim return nil, errors.Wrap(err, errMessage) } - audValidation := jwt.WithoutAudienceValidation() - if expectedAudience != "" { - audValidation = jwt.WithAudience(expectedAudience) - } - token2, err := jwt.ParseWithClaims(accessToken, customClaims, func(token *jwt.Token) (interface{}, error) { // Don't forget to validate the alg is what you expect: if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return rsaPublicKey, nil - }, audValidation) + }) if err != nil { return nil, errors.Wrap(err, errMessage) diff --git a/pkg/jwx/models.go b/pkg/jwx/models.go index 57d51055..48b7449a 100644 --- a/pkg/jwx/models.go +++ b/pkg/jwx/models.go @@ -1,6 +1,6 @@ package jwx -import jwt "github.com/dgrijalva/jwt-go/v4" +import jwt "github.com/golang-jwt/jwt/v4" // DecodedAccessTokenHeader is the decoded header from the access token type DecodedAccessTokenHeader struct { diff --git a/utils_test.go b/utils_test.go index 9725e68f..c1db3faf 100644 --- a/utils_test.go +++ b/utils_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/Nerzal/gocloak/v9" + "github.com/Nerzal/gocloak/v10" ) func TestStringP(t *testing.T) {