From edd8587ab2bdeb6bf2aef78bc7109becb46a55af Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Tue, 13 Sep 2022 21:41:10 -0400 Subject: [PATCH] make sure that the jwt encryption key is configurable by the end user. --- backend/pkg/auth/utils.go | 11 ++++------- backend/pkg/web/handler/auth.go | 7 +++++-- backend/pkg/web/middleware/require_auth.go | 6 +++++- config.yaml | 3 +++ 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/backend/pkg/auth/utils.go b/backend/pkg/auth/utils.go index cbcd4e43..e3195908 100644 --- a/backend/pkg/auth/utils.go +++ b/backend/pkg/auth/utils.go @@ -6,9 +6,6 @@ import ( "time" ) -//TODO: this key should be dynamically generated/taken from config file. -var jwtKey = []byte("supersecretkey") - //TODO: this should match the ID and username for the user. type JWTClaim struct { Username string `json:"username"` @@ -16,7 +13,7 @@ type JWTClaim struct { jwt.StandardClaims } -func GenerateJWT(username string) (tokenString string, err error) { +func GenerateJWT(encryptionKey string, username string) (tokenString string, err error) { expirationTime := time.Now().Add(2 * time.Hour) claims := &JWTClaim{ Username: username, @@ -26,11 +23,11 @@ func GenerateJWT(username string) (tokenString string, err error) { }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) - tokenString, err = token.SignedString(jwtKey) + tokenString, err = token.SignedString([]byte(encryptionKey)) return } -func ValidateToken(signedToken string) (*JWTClaim, error) { +func ValidateToken(encryptionKey string, signedToken string) (*JWTClaim, error) { token, err := jwt.ParseWithClaims( signedToken, &JWTClaim{}, @@ -38,7 +35,7 @@ func ValidateToken(signedToken string) (*JWTClaim, error) { if jwt.SigningMethodHS256 != token.Method { return nil, errors.New("Invalid signing algorithm") } - return []byte(jwtKey), nil + return []byte(encryptionKey), nil }, ) if err != nil { diff --git a/backend/pkg/web/handler/auth.go b/backend/pkg/web/handler/auth.go index 9ceea0a5..aac203af 100644 --- a/backend/pkg/web/handler/auth.go +++ b/backend/pkg/web/handler/auth.go @@ -3,6 +3,7 @@ package handler import ( "fmt" "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/auth" + "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/config" "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/database" "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/models" "github.com/gin-gonic/gin" @@ -11,6 +12,7 @@ import ( func AuthSignup(c *gin.Context) { databaseRepo := c.MustGet("REPOSITORY").(database.DatabaseRepository) + appConfig := c.MustGet("CONFIG").(config.Interface) var user models.User if err := c.ShouldBindJSON(&user); err != nil { @@ -24,7 +26,7 @@ func AuthSignup(c *gin.Context) { } // return JWT - tokenString, err := auth.GenerateJWT(user.Username) + tokenString, err := auth.GenerateJWT(appConfig.GetString("web.jwt.encryptionKey"), user.Username) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return @@ -35,6 +37,7 @@ func AuthSignup(c *gin.Context) { func AuthSignin(c *gin.Context) { databaseRepo := c.MustGet("REPOSITORY").(database.DatabaseRepository) + appConfig := c.MustGet("CONFIG").(config.Interface) var user models.User if err := c.ShouldBindJSON(&user); err != nil { @@ -55,7 +58,7 @@ func AuthSignin(c *gin.Context) { } // return JWT - tokenString, err := auth.GenerateJWT(user.Username) + tokenString, err := auth.GenerateJWT(appConfig.GetString("web.jwt.encryptionKey"), user.Username) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "an error occurred generating JWT token"}) return diff --git a/backend/pkg/web/middleware/require_auth.go b/backend/pkg/web/middleware/require_auth.go index 0c56044e..8f967758 100644 --- a/backend/pkg/web/middleware/require_auth.go +++ b/backend/pkg/web/middleware/require_auth.go @@ -2,6 +2,7 @@ package middleware import ( "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/auth" + "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/config" "github.com/gin-gonic/gin" "log" "net/http" @@ -10,6 +11,8 @@ import ( func RequireAuth() gin.HandlerFunc { return func(c *gin.Context) { + appConfig := c.MustGet("CONFIG").(config.Interface) + authHeader := c.GetHeader("Authorization") authHeaderParts := strings.Split(authHeader, " ") @@ -27,13 +30,14 @@ func RequireAuth() gin.HandlerFunc { c.Abort() return } - claim, err := auth.ValidateToken(tokenString) + claim, err := auth.ValidateToken(appConfig.GetString("web.jwt.encryptionKey"), tokenString) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{"success": false, "error": err.Error()}) c.Abort() return } + //todo, is this shared between all sessions?? c.Set("AUTH_TOKEN", tokenString) c.Set("AUTH_USERNAME", claim.Username) diff --git a/config.yaml b/config.yaml index bc5d5c42..eb1dc5f0 100644 --- a/config.yaml +++ b/config.yaml @@ -6,6 +6,9 @@ version: 1 web: + jwt: + # used to encrypt/validate JWT session key (used for authentication) + encryptionKey: 'changethissupersecretkey' listen: port: 9090 host: 0.0.0.0