From 1146468a03cf822665947300bf378765ea671c5b Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Mon, 30 May 2022 11:00:00 +0530 Subject: [PATCH] fix: memory store upgrade in token helpers --- server/token/admin_token.go | 19 +++++-- server/token/auth_token.go | 42 ++++++++++++--- server/token/jwt.go | 85 +++++++++++++++++++++++------- server/token/verification_token.go | 6 ++- 4 files changed, 122 insertions(+), 30 deletions(-) diff --git a/server/token/admin_token.go b/server/token/admin_token.go index dd8a25f..9dcbeb3 100644 --- a/server/token/admin_token.go +++ b/server/token/admin_token.go @@ -13,7 +13,11 @@ import ( // CreateAdminAuthToken creates the admin token based on secret key func CreateAdminAuthToken(tokenType string, c *gin.Context) (string, error) { - return crypto.EncryptPassword(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) + if err != nil { + return "", err + } + return crypto.EncryptPassword(adminSecret) } // GetAdminAuthToken helps in getting the admin token from the request cookie @@ -23,7 +27,11 @@ func GetAdminAuthToken(gc *gin.Context) (string, error) { return "", fmt.Errorf("unauthorized") } - err = bcrypt.CompareHashAndPassword([]byte(token), []byte(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))) + adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) + if err != nil { + return "", err + } + err = bcrypt.CompareHashAndPassword([]byte(token), []byte(adminSecret)) if err != nil { return "", fmt.Errorf(`unauthorized`) @@ -40,8 +48,11 @@ func IsSuperAdmin(gc *gin.Context) bool { if secret == "" { return false } - - return secret == memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) + adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) + if err != nil { + return false + } + return secret == adminSecret } return token != "" diff --git a/server/token/auth_token.go b/server/token/auth_token.go index c66aa25..aea5af2 100644 --- a/server/token/auth_token.go +++ b/server/token/auth_token.go @@ -106,9 +106,13 @@ func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonc // expires in 1 year expiryBound := time.Hour * 8760 expiresAt := time.Now().Add(expiryBound).Unix() + clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID) + if err != nil { + return "", 0, err + } customClaims := jwt.MapClaims{ "iss": hostname, - "aud": memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID), + "aud": clientID, "sub": user.ID, "exp": expiresAt, "iat": time.Now().Unix(), @@ -129,16 +133,24 @@ func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonc // CreateAccessToken util to create JWT token, based on // user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT func CreateAccessToken(user models.User, roles, scopes []string, hostName, nonce string) (string, int64, error) { - expiryBound, err := utils.ParseDurationInSeconds(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime)) + expireTime, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime) + if err != nil { + return "", 0, err + } + expiryBound, err := utils.ParseDurationInSeconds(expireTime) if err != nil { expiryBound = time.Minute * 30 } expiresAt := time.Now().Add(expiryBound).Unix() + clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID) + if err != nil { + return "", 0, err + } customClaims := jwt.MapClaims{ "iss": hostName, - "aud": memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID), + "aud": clientID, "nonce": nonce, "sub": user.ID, "exp": expiresAt, @@ -285,7 +297,11 @@ func ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionD // CreateIDToken util to create JWT token, based on // user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT func CreateIDToken(user models.User, roles []string, hostname, nonce string) (string, int64, error) { - expiryBound, err := utils.ParseDurationInSeconds(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime)) + expireTime, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime) + if err != nil { + return "", 0, err + } + expiryBound, err := utils.ParseDurationInSeconds(expireTime) if err != nil { expiryBound = time.Minute * 30 } @@ -297,10 +313,18 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce string) (st var userMap map[string]interface{} json.Unmarshal(userBytes, &userMap) - claimKey := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtRoleClaim) + claimKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtRoleClaim) + if err != nil { + claimKey = "roles" + } + + clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID) + if err != nil { + return "", 0, err + } customClaims := jwt.MapClaims{ "iss": hostname, - "aud": memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID), + "aud": clientID, "nonce": nonce, "sub": user.ID, "exp": expiresAt, @@ -317,7 +341,11 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce string) (st } // check for the extra access token script - accessTokenScript := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyCustomAccessTokenScript) + accessTokenScript, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyCustomAccessTokenScript) + if err != nil { + log.Debug("Failed to get custom access token script: ", err) + accessTokenScript = "" + } if accessTokenScript != "" { vm := otto.New() diff --git a/server/token/jwt.go b/server/token/jwt.go index 936a8d3..350c2f5 100644 --- a/server/token/jwt.go +++ b/server/token/jwt.go @@ -11,7 +11,10 @@ import ( // SignJWTToken common util to sing jwt token func SignJWTToken(claims jwt.MapClaims) (string, error) { - jwtType := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType) + jwtType, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType) + if err != nil { + return "", err + } signingMethod := jwt.GetSigningMethod(jwtType) if signingMethod == nil { return "", errors.New("unsupported signing method") @@ -24,15 +27,27 @@ func SignJWTToken(claims jwt.MapClaims) (string, error) { switch signingMethod { case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512: - return t.SignedString([]byte(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret))) + jwtSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret) + if err != nil { + return "", err + } + return t.SignedString([]byte(jwtSecret)) case jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512: - key, err := crypto.ParseRsaPrivateKeyFromPemStr(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPrivateKey)) + jwtPrivateKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPrivateKey) + if err != nil { + return "", err + } + key, err := crypto.ParseRsaPrivateKeyFromPemStr(jwtPrivateKey) if err != nil { return "", err } return t.SignedString(key) case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512: - key, err := crypto.ParseEcdsaPrivateKeyFromPemStr(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPrivateKey)) + jwtPrivateKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPrivateKey) + if err != nil { + return "", err + } + key, err := crypto.ParseEcdsaPrivateKeyFromPemStr(jwtPrivateKey) if err != nil { return "", err } @@ -45,20 +60,30 @@ func SignJWTToken(claims jwt.MapClaims) (string, error) { // ParseJWTToken common util to parse jwt token func ParseJWTToken(token, hostname, nonce, subject string) (jwt.MapClaims, error) { - jwtType := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType) + jwtType, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType) + if err != nil { + return nil, err + } signingMethod := jwt.GetSigningMethod(jwtType) - var err error var claims jwt.MapClaims switch signingMethod { case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512: _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { - return []byte(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret)), nil + jwtSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret) + if err != nil { + return nil, err + } + return []byte(jwtSecret), nil }) case jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512: _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { - key, err := crypto.ParseRsaPublicKeyFromPemStr(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)) + jwtPublicKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey) + if err != nil { + return nil, err + } + key, err := crypto.ParseRsaPublicKeyFromPemStr(jwtPublicKey) if err != nil { return nil, err } @@ -66,7 +91,11 @@ func ParseJWTToken(token, hostname, nonce, subject string) (jwt.MapClaims, error }) case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512: _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { - key, err := crypto.ParseEcdsaPublicKeyFromPemStr(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)) + jwtPublicKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey) + if err != nil { + return nil, err + } + key, err := crypto.ParseEcdsaPublicKeyFromPemStr(jwtPublicKey) if err != nil { return nil, err } @@ -86,8 +115,11 @@ func ParseJWTToken(token, hostname, nonce, subject string) (jwt.MapClaims, error intIat := int64(claims["iat"].(float64)) claims["exp"] = intExp claims["iat"] = intIat - - if claims["aud"] != memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID) { + clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID) + if err != nil { + return claims, err + } + if claims["aud"] != clientID { return claims, errors.New("invalid audience") } @@ -109,20 +141,30 @@ func ParseJWTToken(token, hostname, nonce, subject string) (jwt.MapClaims, error // ParseJWTTokenWithoutNonce common util to parse jwt token without nonce // used to validate ID token as it is not persisted in store func ParseJWTTokenWithoutNonce(token, hostname string) (jwt.MapClaims, error) { - jwtType := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType) + jwtType, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType) + if err != nil { + return nil, err + } signingMethod := jwt.GetSigningMethod(jwtType) - var err error var claims jwt.MapClaims switch signingMethod { case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512: _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { - return []byte(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret)), nil + jwtSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret) + if err != nil { + return nil, err + } + return []byte(jwtSecret), nil }) case jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512: _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { - key, err := crypto.ParseRsaPublicKeyFromPemStr(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)) + jwtPublicKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey) + if err != nil { + return nil, err + } + key, err := crypto.ParseRsaPublicKeyFromPemStr(jwtPublicKey) if err != nil { return nil, err } @@ -130,7 +172,11 @@ func ParseJWTTokenWithoutNonce(token, hostname string) (jwt.MapClaims, error) { }) case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512: _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { - key, err := crypto.ParseEcdsaPublicKeyFromPemStr(memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)) + jwtPublicKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey) + if err != nil { + return nil, err + } + key, err := crypto.ParseEcdsaPublicKeyFromPemStr(jwtPublicKey) if err != nil { return nil, err } @@ -150,8 +196,11 @@ func ParseJWTTokenWithoutNonce(token, hostname string) (jwt.MapClaims, error) { intIat := int64(claims["iat"].(float64)) claims["exp"] = intExp claims["iat"] = intIat - - if claims["aud"] != memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID) { + clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID) + if err != nil { + return claims, err + } + if claims["aud"] != clientID { return claims, errors.New("invalid audience") } diff --git a/server/token/verification_token.go b/server/token/verification_token.go index 4f3b4c5..75aef30 100644 --- a/server/token/verification_token.go +++ b/server/token/verification_token.go @@ -10,9 +10,13 @@ import ( // CreateVerificationToken creates a verification JWT token func CreateVerificationToken(email, tokenType, hostname, nonceHash, redirectURL string) (string, error) { + clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID) + if err != nil { + return "", err + } claims := jwt.MapClaims{ "iss": hostname, - "aud": memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID), + "aud": clientID, "sub": email, "exp": time.Now().Add(time.Minute * 30).Unix(), "iat": time.Now().Unix(),