diff --git a/consent/strategy_default.go b/consent/strategy_default.go index bfa95d158ab..7448440b291 100644 --- a/consent/strategy_default.go +++ b/consent/strategy_default.go @@ -35,8 +35,8 @@ import ( "github.com/ory/x/sqlcon" - jwtgo "github.com/dgrijalva/jwt-go" "github.com/gorilla/sessions" + jwtgo "github.com/ory/fosite/token/jwt" "github.com/pborman/uuid" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -190,13 +190,7 @@ func (s *DefaultStrategy) getIDTokenHintClaims(ctx context.Context, idTokenHint } else if err != nil { return nil, errorsx.WithStack(fosite.ErrInvalidRequest.WithHint(err.Error())) } - - claims, ok := token.Claims.(jwtgo.MapClaims) - if !ok { - return nil, errorsx.WithStack(fosite.ErrInvalidRequest.WithHint("Failed to validate OpenID Connect request as decoding id token from id_token_hint to jwt.MapClaims failed.")) - } - - return claims, nil + return token.Claims, nil } func (s *DefaultStrategy) getSubjectFromIDTokenHint(ctx context.Context, idTokenHint string) (string, error) { diff --git a/consent/strategy_default_test.go b/consent/strategy_default_test.go index bfe159dc179..303c02c6375 100644 --- a/consent/strategy_default_test.go +++ b/consent/strategy_default_test.go @@ -27,7 +27,7 @@ import ( "net/http/httptest" "testing" - jwtgo "github.com/dgrijalva/jwt-go" + jwtgo "github.com/ory/fosite/token/jwt" "github.com/stretchr/testify/require" "github.com/ory/fosite/token/jwt" @@ -122,7 +122,7 @@ func newAuthCookieJar(t *testing.T, reg driver.Registry, u, sessionID string) ht return cj } -func genIDToken(t *testing.T, reg driver.Registry, c jwtgo.Claims) string { +func genIDToken(t *testing.T, reg driver.Registry, c jwtgo.MapClaims) string { r, _, err := reg.OpenIDJWTStrategy().Generate(context.TODO(), c, jwt.NewHeaders()) require.NoError(t, err) return r diff --git a/consent/strategy_logout_test.go b/consent/strategy_logout_test.go index a77bf619ba0..4a03e429e56 100644 --- a/consent/strategy_logout_test.go +++ b/consent/strategy_logout_test.go @@ -12,7 +12,7 @@ import ( "testing" "time" - jwtgo "github.com/dgrijalva/jwt-go" + jwtgo "github.com/ory/fosite/token/jwt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tidwall/gjson" @@ -258,7 +258,7 @@ func TestLogoutFlows(t *testing.T) { acceptLoginAs(t, "aeneas-rekkas") checkAndAcceptLogout(t, nil, nil) - expectedMessage := "token contains an invalid number of segments" + expectedMessage := "compact JWS format must have three parts" browser := createBrowserWithSession(t, createSampleClient(t)) values := url.Values{"state": {"1234"}, "post_logout_redirect_uri": {customPostLogoutURL}, "id_token_hint": {"i am not valid"}} t.Run("method=get", testExpectErrorPage(browser, http.MethodGet, values, expectedMessage)) diff --git a/go.mod b/go.mod index 09423890825..de4f3cd0977 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,6 @@ require ( github.com/DataDog/datadog-go v4.6.0+incompatible // indirect github.com/cenkalti/backoff/v3 v3.0.0 github.com/containerd/containerd v1.4.4 // indirect - github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/evanphx/json-patch v0.5.2 github.com/go-bindata/go-bindata v3.1.1+incompatible github.com/go-openapi/errors v0.20.0 @@ -44,11 +43,11 @@ require ( github.com/mattn/go-colorable v0.1.7 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 - github.com/oleiade/reflections v1.0.0 + github.com/oleiade/reflections v1.0.1 github.com/olekukonko/tablewriter v0.0.1 github.com/ory/analytics-go/v4 v4.0.1 github.com/ory/cli v0.0.49 - github.com/ory/fosite v0.39.0 + github.com/ory/fosite v0.40.2 github.com/ory/go-acc v0.2.6 github.com/ory/graceful v0.1.1 github.com/ory/herodot v0.9.3 @@ -65,7 +64,6 @@ require ( github.com/sawadashota/encrypta v0.0.2 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.1.3 - github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518 // indirect github.com/stretchr/testify v1.7.0 github.com/tidwall/gjson v1.7.1 github.com/toqueteos/webbrowser v1.2.0 diff --git a/go.sum b/go.sum index 9f4bc4d5872..bf224b8d2d2 100644 --- a/go.sum +++ b/go.sum @@ -1099,8 +1099,9 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/oleiade/reflections v1.0.0 h1:0ir4pc6v8/PJ0yw5AEtMddfXpWBXg9cnG7SgSoJuCgY= github.com/oleiade/reflections v1.0.0/go.mod h1:RbATFBbKYkVdqmSFtx13Bb/tVhR0lgOBXunWTZKeL4w= +github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM= +github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= @@ -1153,11 +1154,10 @@ github.com/ory/dockertest/v3 v3.6.2/go.mod h1:EFLcVUOl8qCwp9NyDAcCDtq/QviLtYswW/ github.com/ory/dockertest/v3 v3.6.3 h1:L8JWiGgR+fnj90AEOkTFIEp4j5uWAK72P3IUsYgn2cs= github.com/ory/dockertest/v3 v3.6.3/go.mod h1:EFLcVUOl8qCwp9NyDAcCDtq/QviLtYswW/VbWzUnTNE= github.com/ory/fosite v0.29.0/go.mod h1:0atSZmXO7CAcs6NPMI/Qtot8tmZYj04Nddoold4S2h0= -github.com/ory/fosite v0.39.0 h1:u1Ct/ME7XYzREvufr7ehBIdq/KatjVLIYg/ABqWzprw= -github.com/ory/fosite v0.39.0/go.mod h1:37r59qkOSPueYKmaA7EHiXrDMF1B+XPN+MgkZgTRg3Y= +github.com/ory/fosite v0.40.2 h1:xOS/1kPOlk1LqnAEnNXUqNGdMwvHBqw20ZbURaK+qoM= +github.com/ory/fosite v0.40.2/go.mod h1:KbDZzqSDLaOLDN2haRIsBQHUhl8MQp66cYMqCpO/8Mg= github.com/ory/go-acc v0.0.0-20181118080137-ddc355013f90/go.mod h1:sxnvPCxChFuSmTJGj8FdMupeq1BezCiEpDjTUXQ4hf4= github.com/ory/go-acc v0.1.0/go.mod h1:0omgy2aa3nDBJ45VAKeLHH8ccPBudxLeic4xiDRtug0= -github.com/ory/go-acc v0.2.5/go.mod h1:4Kb/UnPcT8qRAk3IAxta+hvVapdxTLWtrr7bFLlEgpw= github.com/ory/go-acc v0.2.6 h1:YfI+L9dxI7QCtWn2RbawqO0vXhiThdXu/RgizJBbaq0= github.com/ory/go-acc v0.2.6/go.mod h1:4Kb/UnPcT8qRAk3IAxta+hvVapdxTLWtrr7bFLlEgpw= github.com/ory/go-convenience v0.1.0 h1:zouLKfF2GoSGnJwGq+PE/nJAE6dj2Zj5QlTgmMTsTS8= @@ -1201,15 +1201,13 @@ github.com/ory/x v0.0.85/go.mod h1:s44V8t3xyjWZREcU+mWlp4h302rTuM4aLXcW+y5FbQ8= github.com/ory/x v0.0.93/go.mod h1:lfcTaGXpTZs7IEQAW00r9EtTCOxD//SiP5uWtNiz31g= github.com/ory/x v0.0.110/go.mod h1:DJfkE3GdakhshNhw4zlKoRaL/ozg/lcTahA9OCih2BE= github.com/ory/x v0.0.127/go.mod h1:FwUujfFuCj5d+xgLn4fGMYPnzriR5bdAIulFXMtnK0M= -github.com/ory/x v0.0.162/go.mod h1:sj3z/MeCrAyNFFTfN6yK1nTmHXGSFnw+QwIIQ/Rowec= github.com/ory/x v0.0.166/go.mod h1:gT/3K0mSFaPllJgoFrvKYIBYI5W1Nz5RxQTJCGrIwDY= github.com/ory/x v0.0.179/go.mod h1:SGETCUk1DgQC30bb7y4hjhkKGQ1x0YOsldrmGmy6MNc= github.com/ory/x v0.0.181/go.mod h1:SGETCUk1DgQC30bb7y4hjhkKGQ1x0YOsldrmGmy6MNc= github.com/ory/x v0.0.189/go.mod h1:uJK3Re/AF6F3LCNnwqzeU/ftmexCpjqwfdyrDc6PbcM= github.com/ory/x v0.0.205/go.mod h1:A1s4iwmFIppRXZLF3J9GGWeY/HpREVm0Dk5z/787iek= github.com/ory/x v0.0.207/go.mod h1:sBgvUAcmc2lmtOBe5VMcV2vNAlADT4bkFHomG29y7N4= -github.com/ory/x v0.0.233 h1:AiBvucFkE054XJ04OnUziM9Ect5nR/NbMe5101EBjVE= -github.com/ory/x v0.0.233/go.mod h1:0mSGWLFgcqckIvgexka1GJK/sshYrFFkU7lPajzGTFw= +github.com/ory/x v0.0.212/go.mod h1:RDxYOolvMdzumYnHWha8D+RoLjYtGszyDDed4OCGC54= github.com/ory/x v0.0.237 h1:sFcWr8EcOYrPb30tsWk3BZM7jdzHeBAqaOSHveizmfs= github.com/ory/x v0.0.237/go.mod h1:KPgNsUzpztH15EZdw5HjurtTe+mXQ34yqMCCTb5BZAc= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= @@ -1777,7 +1775,6 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1896,7 +1893,6 @@ golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200721223218-6123e77877b2/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= diff --git a/internal/testhelpers/oauth2.go b/internal/testhelpers/oauth2.go index 35fa65c1954..44af0b8ef52 100644 --- a/internal/testhelpers/oauth2.go +++ b/internal/testhelpers/oauth2.go @@ -9,7 +9,7 @@ import ( "testing" "time" - djwt "github.com/dgrijalva/jwt-go" + djwt "github.com/ory/fosite/token/jwt" "github.com/stretchr/testify/assert" "github.com/ory/fosite/token/jwt" @@ -80,7 +80,7 @@ func DecodeIDToken(t *testing.T, token *oauth2.Token) gjson.Result { require.True(t, ok) assert.NotEmpty(t, idt) - body, err := djwt.DecodeSegment(strings.Split(idt, ".")[1]) + body, err := x.DecodeSegment(strings.Split(idt, ".")[1]) require.NoError(t, err) return gjson.ParseBytes(body) diff --git a/jwk/jwt_strategy.go b/jwk/jwt_strategy.go index ec86b279bcf..a713a3e2d42 100644 --- a/jwk/jwt_strategy.go +++ b/jwk/jwt_strategy.go @@ -28,7 +28,7 @@ import ( "github.com/ory/hydra/driver/config" - jwt2 "github.com/dgrijalva/jwt-go" + jwt2 "github.com/ory/fosite/token/jwt" "github.com/pkg/errors" "github.com/ory/fosite/token/jwt" @@ -75,7 +75,7 @@ func (j *RS256JWTStrategy) GetSignature(ctx context.Context, token string) (stri return j.RS256JWTStrategy.GetSignature(ctx, token) } -func (j *RS256JWTStrategy) Generate(ctx context.Context, claims jwt2.Claims, header jwt.Mapper) (string, string, error) { +func (j *RS256JWTStrategy) Generate(ctx context.Context, claims jwt2.MapClaims, header jwt.Mapper) (string, string, error) { if err := j.refresh(ctx); err != nil { return "", "", err } diff --git a/jwk/jwt_strategy_test.go b/jwk/jwt_strategy_test.go index c52788edd98..faa8c20a006 100644 --- a/jwk/jwt_strategy_test.go +++ b/jwk/jwt_strategy_test.go @@ -26,7 +26,7 @@ import ( "github.com/ory/hydra/internal" - jwt2 "github.com/dgrijalva/jwt-go" + jwt2 "github.com/ory/fosite/token/jwt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/oauth2/handler.go b/oauth2/handler.go index 694c75f236b..c5ea22bbda6 100644 --- a/oauth2/handler.go +++ b/oauth2/handler.go @@ -33,8 +33,8 @@ import ( "github.com/ory/x/errorsx" - jwt2 "github.com/dgrijalva/jwt-go" "github.com/julienschmidt/httprouter" + jwt2 "github.com/ory/fosite/token/jwt" "github.com/pkg/errors" "github.com/ory/fosite" diff --git a/oauth2/handler_test.go b/oauth2/handler_test.go index db197e6c395..989fa74fa19 100644 --- a/oauth2/handler_test.go +++ b/oauth2/handler_test.go @@ -46,8 +46,8 @@ import ( "github.com/ory/hydra/internal" "github.com/ory/x/urlx" - jwt2 "github.com/dgrijalva/jwt-go" "github.com/golang/mock/gomock" + jwt2 "github.com/ory/fosite/token/jwt" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -373,9 +373,9 @@ func TestUserinfo(t *testing.T) { return jwk.MustRSAPublic(key), nil }) require.NoError(t, err) - assert.EqualValues(t, "alice", claims.Claims.(jwt2.MapClaims)["sub"]) - assert.EqualValues(t, []interface{}{"foobar-client"}, claims.Claims.(jwt2.MapClaims)["aud"], "%#v", claims.Claims) - assert.NotEmpty(t, claims.Claims.(jwt2.MapClaims)["jti"]) + assert.EqualValues(t, "alice", claims.Claims["sub"]) + assert.EqualValues(t, []interface{}{"foobar-client"}, claims.Claims["aud"], "%#v", claims.Claims) + assert.NotEmpty(t, claims.Claims["jti"]) }, }, } { diff --git a/oauth2/oauth2_auth_code_test.go b/oauth2/oauth2_auth_code_test.go index cf1999a469b..5d90999fe1c 100644 --- a/oauth2/oauth2_auth_code_test.go +++ b/oauth2/oauth2_auth_code_test.go @@ -40,7 +40,6 @@ import ( "github.com/ory/hydra/client" "github.com/ory/hydra/internal/testhelpers" - djwt "github.com/dgrijalva/jwt-go" "github.com/julienschmidt/httprouter" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -201,7 +200,7 @@ func TestAuthCodeWithDefaultStrategy(t *testing.T) { require.True(t, ok) assert.NotEmpty(t, idt) - body, err := djwt.DecodeSegment(strings.Split(idt, ".")[1]) + body, err := x.DecodeSegment(strings.Split(idt, ".")[1]) require.NoError(t, err) claims := gjson.ParseBytes(body) @@ -241,7 +240,7 @@ func TestAuthCodeWithDefaultStrategy(t *testing.T) { } require.Len(t, parts, 3) - body, err := djwt.DecodeSegment(parts[1]) + body, err := x.DecodeSegment(parts[1]) require.NoError(t, err) i := gjson.ParseBytes(body) @@ -658,7 +657,7 @@ func TestAuthCodeWithMockStrategy(t *testing.T) { return } - body, err := djwt.DecodeSegment(strings.Split(token, ".")[1]) + body, err := x.DecodeSegment(strings.Split(token, ".")[1]) require.NoError(t, err) data := map[string]interface{}{} @@ -867,13 +866,13 @@ func TestAuthCodeWithMockStrategy(t *testing.T) { t.Skip() } - body, err := djwt.DecodeSegment(strings.Split(token.AccessToken, ".")[1]) + body, err := x.DecodeSegment(strings.Split(token.AccessToken, ".")[1]) require.NoError(t, err) origPayload := map[string]interface{}{} require.NoError(t, json.Unmarshal(body, &origPayload)) - body, err = djwt.DecodeSegment(strings.Split(refreshedToken.AccessToken, ".")[1]) + body, err = x.DecodeSegment(strings.Split(refreshedToken.AccessToken, ".")[1]) require.NoError(t, err) refreshedPayload := map[string]interface{}{} diff --git a/oauth2/oauth2_client_credentials_test.go b/oauth2/oauth2_client_credentials_test.go index 9735c7460d7..bbca408eecb 100644 --- a/oauth2/oauth2_client_credentials_test.go +++ b/oauth2/oauth2_client_credentials_test.go @@ -30,7 +30,6 @@ import ( "github.com/google/uuid" "github.com/tidwall/gjson" - "github.com/dgrijalva/jwt-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" goauth2 "golang.org/x/oauth2" @@ -41,6 +40,7 @@ import ( hc "github.com/ory/hydra/client" "github.com/ory/hydra/driver/config" "github.com/ory/hydra/internal" + "github.com/ory/hydra/x" ) func TestClientCredentials(t *testing.T) { @@ -108,7 +108,7 @@ func TestClientCredentials(t *testing.T) { return } - body, err := jwt.DecodeSegment(strings.Split(token.AccessToken, ".")[1]) + body, err := x.DecodeSegment(strings.Split(token.AccessToken, ".")[1]) require.NoError(t, err) jwtClaims := gjson.ParseBytes(body) diff --git a/test/mock-client/main.go b/test/mock-client/main.go index 0f667465b69..8be757e56b2 100644 --- a/test/mock-client/main.go +++ b/test/mock-client/main.go @@ -34,11 +34,11 @@ import ( "strings" "time" - "github.com/dgrijalva/jwt-go" "golang.org/x/oauth2" hydra "github.com/ory/hydra/internal/httpclient/client" "github.com/ory/hydra/internal/httpclient/client/admin" + "github.com/ory/hydra/x" "github.com/ory/x/cmdx" "github.com/ory/x/urlx" ) @@ -173,7 +173,7 @@ func checkTokenResponse(token oauth2token) { log.Fatalf("JWT Access Token does not seem to have three parts: %d - %+v - %v", len(parts), token, parts) } - payload, err := jwt.DecodeSegment(parts[1]) + payload, err := x.DecodeSegment(parts[1]) if err != nil { log.Fatalf("Unable to decode id token segment: %s", err) } @@ -221,7 +221,7 @@ func checkTokenResponse(token oauth2token) { log.Fatalf("ID Token does not seem to have three parts: %d - %+v - %v", len(parts), token, parts) } - payload, err := jwt.DecodeSegment(parts[1]) + payload, err := x.DecodeSegment(parts[1]) if err != nil { log.Fatalf("Unable to decode id token segment: %s", err) } diff --git a/x/jwt.go b/x/jwt.go new file mode 100644 index 00000000000..fe3fefdf588 --- /dev/null +++ b/x/jwt.go @@ -0,0 +1,15 @@ +package x + +import ( + "encoding/base64" + "strings" +) + +// Decode JWT specific base64url encoding with padding stripped +func DecodeSegment(seg string) ([]byte, error) { + if l := len(seg) % 4; l > 0 { + seg += strings.Repeat("=", 4-l) + } + + return base64.URLEncoding.DecodeString(seg) +}