From 5aafe5319b01cf25d707d63b16b49955c7422fae Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Wed, 10 Nov 2021 14:18:17 +0100 Subject: [PATCH] Improve how JWT is generated from the CLI --- auth/commands/commands.go | 5 ++++- auth/oauth2/jwt_access.go | 2 ++ pkg/auth/interfaces.go | 8 ++------ pkg/auth/jwt.go | 22 +++++++++++++++++----- pkg/corredor/service.go | 1 - 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/auth/commands/commands.go b/auth/commands/commands.go index 963cf6bb6..c18493671 100644 --- a/auth/commands/commands.go +++ b/auth/commands/commands.go @@ -91,6 +91,7 @@ func Command(ctx context.Context, app serviceInitializer, storeInit func(ctx con Run: func(cmd *cobra.Command, args []string) { ctx = auth.SetIdentityToContext(ctx, auth.ServiceUser()) var ( + at string user *types.User err error @@ -103,7 +104,9 @@ func Command(ctx context.Context, app serviceInitializer, storeInit func(ctx con err = service.DefaultAuth.LoadRoleMemberships(ctx, user) cli.HandleError(err) - cmd.Println(auth.DefaultJwtHandler.Encode(user)) + at, err = auth.DefaultJwtHandler.Generate(ctx, user) + cli.HandleError(err) + cmd.Println(at) }, } diff --git a/auth/oauth2/jwt_access.go b/auth/oauth2/jwt_access.go index d24d08fcb..17c0a7adb 100644 --- a/auth/oauth2/jwt_access.go +++ b/auth/oauth2/jwt_access.go @@ -11,6 +11,8 @@ import ( ) // NewJWTAccessGenerate create to generate the jwt access token instance +// +// @todo move this to pkg/auth (??) so it can be re-used func NewJWTAccessGenerate(kid string, key []byte, method jwt.SigningMethod) *JWTAccessGenerate { return &JWTAccessGenerate{ SignedKeyID: kid, diff --git a/pkg/auth/interfaces.go b/pkg/auth/interfaces.go index d4f3d0001..5af129409 100644 --- a/pkg/auth/interfaces.go +++ b/pkg/auth/interfaces.go @@ -2,8 +2,9 @@ package auth import ( "context" - "github.com/dgrijalva/jwt-go" "net/http" + + "github.com/dgrijalva/jwt-go" ) type ( @@ -14,16 +15,11 @@ type ( String() string } - TokenEncoder interface { - Encode(identity Identifiable, scope ...string) string - } - TokenGenerator interface { Generate(ctx context.Context, identity Identifiable) (string, error) } TokenHandler interface { - TokenEncoder TokenGenerator Authenticate(token string) (jwt.MapClaims, error) HttpVerifier() func(http.Handler) http.Handler diff --git a/pkg/auth/jwt.go b/pkg/auth/jwt.go index eb6046aa3..cef1fb167 100644 --- a/pkg/auth/jwt.go +++ b/pkg/auth/jwt.go @@ -4,13 +4,15 @@ import ( "context" "encoding/json" "fmt" - "github.com/cortezaproject/corteza-server/pkg/id" - "github.com/cortezaproject/corteza-server/system/types" "net/http" "strconv" "strings" "time" + "github.com/cortezaproject/corteza-server/pkg/id" + "github.com/cortezaproject/corteza-server/pkg/rand" + "github.com/cortezaproject/corteza-server/system/types" + "github.com/cortezaproject/corteza-server/pkg/api" "github.com/dgrijalva/jwt-go" "github.com/go-chi/jwtauth" @@ -22,6 +24,7 @@ type ( // Expiration time in minutes expiry time.Duration tokenAuth *jwtauth.JWTAuth + secret []byte } tokenStore interface { @@ -60,6 +63,7 @@ func JWT(secret string, expiry time.Duration) (tkn *token, err error) { tkn = &token{ expiry: expiry, tokenAuth: jwtauth.New(jwt.SigningMethodHS512.Alg(), []byte(secret), nil), + secret: []byte(secret), } return tkn, nil @@ -113,21 +117,29 @@ func (t *token) Encode(i Identifiable, scope ...string) string { return t.encode(i, clientID, scope...) } +// encode give identity, clientID & scope into JWT access token (that can be use for API requests) +// +// @todo this follows implementation in auth/oauth2/jwt_access.go +// and should be refactored accordingly (move both into the same location/pkg => here) func (t *token) encode(i Identifiable, clientID uint64, scope ...string) string { roles := "" for _, r := range i.Roles() { roles += fmt.Sprintf(" %d", r) } - _, tkn, _ := t.tokenAuth.Encode(jwt.MapClaims{ + claims := jwt.MapClaims{ "sub": i.String(), "exp": time.Now().Add(t.expiry).Unix(), "aud": fmt.Sprintf("%d", clientID), "scope": strings.Join(scope, " "), "roles": strings.TrimSpace(roles), - }) + } - return tkn + newToken := jwt.NewWithClaims(jwt.SigningMethodHS512, claims) + newToken.Header["salt"] = string(rand.Bytes(32)) + access, _ := newToken.SignedString(t.secret) + + return access } // HttpAuthenticator converts JWT claims into identity and stores it into context diff --git a/pkg/corredor/service.go b/pkg/corredor/service.go index 5f2bd8606..c2de552d5 100644 --- a/pkg/corredor/service.go +++ b/pkg/corredor/service.go @@ -104,7 +104,6 @@ type ( } authTokenMaker interface { - auth.TokenEncoder auth.TokenGenerator } )