From f2549862df26e2ce089f04486266c5387968cc05 Mon Sep 17 00:00:00 2001 From: ibrahim albarghouthi Date: Thu, 20 Jan 2022 00:45:38 +0200 Subject: [PATCH 1/3] adding issuer into jwt claims --- README.md | 4 ++++ api/admin_test.go | 4 ++-- api/audit_test.go | 2 +- api/invite_test.go | 2 +- api/token.go | 7 ++++--- api/user_test.go | 2 +- conf/configuration.go | 1 + example.env | 1 + hack/test.env | 1 + 9 files changed, 16 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 127231ee6..16063e468 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,10 @@ How long tokens are valid for, in seconds. Defaults to 3600 (1 hour). The default JWT audience. Use audiences to group users. +`JWT_ISS` - `string` + +The "iss" (issuer) claim identifies the principal that issued the JWT + `JWT_ADMIN_GROUP_NAME` - `string` The name of the admin group (if enabled). Defaults to `admin`. diff --git a/api/admin_test.go b/api/admin_test.go index 684d40989..2d6c15f77 100644 --- a/api/admin_test.go +++ b/api/admin_test.go @@ -55,7 +55,7 @@ func (ts *AdminTestSuite) makeSuperAdmin(email string) string { u.IsSuperAdmin = true require.NoError(ts.T(), ts.API.db.Create(u), "Error creating user") - token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret) + token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) require.NoError(ts.T(), err, "Error generating access token") p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}} @@ -70,7 +70,7 @@ func (ts *AdminTestSuite) makeSuperAdmin(email string) string { func (ts *AdminTestSuite) makeSystemUser() string { u := models.NewSystemUser(uuid.Nil, ts.Config.JWT.Aud) - token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret) + token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) require.NoError(ts.T(), err, "Error generating access token") p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}} diff --git a/api/audit_test.go b/api/audit_test.go index 8ddc1f8f0..b4c66f8d3 100644 --- a/api/audit_test.go +++ b/api/audit_test.go @@ -52,7 +52,7 @@ func (ts *AuditTestSuite) makeSuperAdmin(email string) string { u.IsSuperAdmin = true require.NoError(ts.T(), ts.API.db.Create(u), "Error creating user") - token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret) + token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) require.NoError(ts.T(), err, "Error generating access token") p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}} diff --git a/api/invite_test.go b/api/invite_test.go index 1e7648812..cd4650f54 100644 --- a/api/invite_test.go +++ b/api/invite_test.go @@ -61,7 +61,7 @@ func (ts *InviteTestSuite) makeSuperAdmin(email string) string { u.IsSuperAdmin = true require.NoError(ts.T(), ts.API.db.Create(u), "Error creating user") - token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret) + token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) require.NoError(ts.T(), err, "Error generating access token") p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}} diff --git a/api/token.go b/api/token.go index c999377ea..ca0e5d2f4 100644 --- a/api/token.go +++ b/api/token.go @@ -139,7 +139,7 @@ func (a *API) RefreshTokenGrant(ctx context.Context, w http.ResponseWriter, r *h return internalServerError(terr.Error()) } - tokenString, terr = generateAccessToken(user, time.Second*time.Duration(config.JWT.Exp), config.JWT.Secret) + tokenString, terr = generateAccessToken(user, time.Second*time.Duration(config.JWT.Exp), config.JWT.Secret, config.JWT.Iss) if terr != nil { return internalServerError("error generating jwt token").WithInternalError(terr) } @@ -163,12 +163,13 @@ func (a *API) RefreshTokenGrant(ctx context.Context, w http.ResponseWriter, r *h }) } -func generateAccessToken(user *models.User, expiresIn time.Duration, secret string) (string, error) { +func generateAccessToken(user *models.User, expiresIn time.Duration, secret string, iss string) (string, error) { claims := &GoTrueClaims{ StandardClaims: jwt.StandardClaims{ Subject: user.ID.String(), Audience: user.Aud, ExpiresAt: time.Now().Add(expiresIn).Unix(), + Issuer: Iss, }, Email: user.Email, AppMetaData: user.AppMetaData, @@ -195,7 +196,7 @@ func (a *API) issueRefreshToken(ctx context.Context, conn *storage.Connection, u return internalServerError("Database error granting user").WithInternalError(terr) } - tokenString, terr = generateAccessToken(user, time.Second*time.Duration(config.JWT.Exp), config.JWT.Secret) + tokenString, terr = generateAccessToken(user, time.Second*time.Duration(config.JWT.Exp), config.JWT.Secret, config.JWT.Iss) if terr != nil { return internalServerError("error generating jwt token").WithInternalError(terr) } diff --git a/api/user_test.go b/api/user_test.go index 85d6ed54a..96abb2833 100644 --- a/api/user_test.go +++ b/api/user_test.go @@ -62,7 +62,7 @@ func (ts *UserTestSuite) TestUser_UpdatePassword() { req := httptest.NewRequest(http.MethodPut, "http://localhost/user", &buffer) req.Header.Set("Content-Type", "application/json") - token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret) + token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) require.NoError(ts.T(), err) req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) diff --git a/conf/configuration.go b/conf/configuration.go index ac0b5fb9d..d3f98a608 100644 --- a/conf/configuration.go +++ b/conf/configuration.go @@ -44,6 +44,7 @@ type DBConfiguration struct { // JWTConfiguration holds all the JWT related configuration. type JWTConfiguration struct { Secret string `json:"secret" required:"true"` + Iss string `json:"iss"` Exp int `json:"exp"` Aud string `json:"aud"` AdminGroupName string `json:"admin_group_name" split_words:"true"` diff --git a/example.env b/example.env index c5618218a..d4542392b 100644 --- a/example.env +++ b/example.env @@ -1,6 +1,7 @@ GOTRUE_JWT_SECRET="CHANGE-THIS! VERY IMPORTANT!" GOTRUE_JWT_EXP=3600 GOTRUE_JWT_AUD=api.netlify.com +GOTRUE_JWT_ISS=api.netlify.com GOTRUE_DB_DRIVER=mysql DATABASE_URL="root@tcp(127.0.0.1:3306)/gotrue_development?parseTime=true&multiStatements=true" GOTRUE_API_HOST=localhost diff --git a/hack/test.env b/hack/test.env index f6e5a45a1..4fb7ef185 100644 --- a/hack/test.env +++ b/hack/test.env @@ -1,6 +1,7 @@ GOTRUE_JWT_SECRET=testsecret GOTRUE_JWT_EXP=3600 GOTRUE_JWT_AUD=api.netlify.com +GOTRUE_JWT_ISS=api.netlify.com GOTRUE_DB_DRIVER=mysql GOTRUE_DB_AUTOMIGRATE=true GOTRUE_DB_NAMESPACE=test From 6e92cabd83a3bc8d3f663a9de4424d9bc36cea4e Mon Sep 17 00:00:00 2001 From: ibrahim albarghouthi Date: Thu, 20 Jan 2022 00:50:04 +0200 Subject: [PATCH 2/3] Fix indent --- api/admin_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/admin_test.go b/api/admin_test.go index 2d6c15f77..3e12144e7 100644 --- a/api/admin_test.go +++ b/api/admin_test.go @@ -55,7 +55,7 @@ func (ts *AdminTestSuite) makeSuperAdmin(email string) string { u.IsSuperAdmin = true require.NoError(ts.T(), ts.API.db.Create(u), "Error creating user") - token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) + token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) require.NoError(ts.T(), err, "Error generating access token") p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}} @@ -70,7 +70,7 @@ func (ts *AdminTestSuite) makeSuperAdmin(email string) string { func (ts *AdminTestSuite) makeSystemUser() string { u := models.NewSystemUser(uuid.Nil, ts.Config.JWT.Aud) - token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) + token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) require.NoError(ts.T(), err, "Error generating access token") p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}} From 764a85cd7301c49c6cfb0faa492c4adb360f729d Mon Sep 17 00:00:00 2001 From: ibrahim albarghouthi Date: Thu, 20 Jan 2022 00:50:37 +0200 Subject: [PATCH 3/3] fix indent --- api/admin_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/admin_test.go b/api/admin_test.go index 3e12144e7..a24eecc92 100644 --- a/api/admin_test.go +++ b/api/admin_test.go @@ -55,7 +55,7 @@ func (ts *AdminTestSuite) makeSuperAdmin(email string) string { u.IsSuperAdmin = true require.NoError(ts.T(), ts.API.db.Create(u), "Error creating user") - token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) + token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) require.NoError(ts.T(), err, "Error generating access token") p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}} @@ -70,7 +70,7 @@ func (ts *AdminTestSuite) makeSuperAdmin(email string) string { func (ts *AdminTestSuite) makeSystemUser() string { u := models.NewSystemUser(uuid.Nil, ts.Config.JWT.Aud) - token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) + token, err := generateAccessToken(u, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret, ts.Config.JWT.Iss) require.NoError(ts.T(), err, "Error generating access token") p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}}