fix: memory store upgrade in token helpers

This commit is contained in:
Lakhan Samani 2022-05-30 11:00:00 +05:30
parent 268b22ffb2
commit 1146468a03
4 changed files with 122 additions and 30 deletions

View File

@ -13,7 +13,11 @@ import (
// CreateAdminAuthToken creates the admin token based on secret key // CreateAdminAuthToken creates the admin token based on secret key
func CreateAdminAuthToken(tokenType string, c *gin.Context) (string, error) { 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 // 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") 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 { if err != nil {
return "", fmt.Errorf(`unauthorized`) return "", fmt.Errorf(`unauthorized`)
@ -40,8 +48,11 @@ func IsSuperAdmin(gc *gin.Context) bool {
if secret == "" { if secret == "" {
return false return false
} }
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
return secret == memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) if err != nil {
return false
}
return secret == adminSecret
} }
return token != "" return token != ""

View File

@ -106,9 +106,13 @@ func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonc
// expires in 1 year // expires in 1 year
expiryBound := time.Hour * 8760 expiryBound := time.Hour * 8760
expiresAt := time.Now().Add(expiryBound).Unix() expiresAt := time.Now().Add(expiryBound).Unix()
clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
if err != nil {
return "", 0, err
}
customClaims := jwt.MapClaims{ customClaims := jwt.MapClaims{
"iss": hostname, "iss": hostname,
"aud": memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID), "aud": clientID,
"sub": user.ID, "sub": user.ID,
"exp": expiresAt, "exp": expiresAt,
"iat": time.Now().Unix(), "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 // CreateAccessToken util to create JWT token, based on
// user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT // user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT
func CreateAccessToken(user models.User, roles, scopes []string, hostName, nonce string) (string, int64, error) { 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 { if err != nil {
expiryBound = time.Minute * 30 expiryBound = time.Minute * 30
} }
expiresAt := time.Now().Add(expiryBound).Unix() expiresAt := time.Now().Add(expiryBound).Unix()
clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
if err != nil {
return "", 0, err
}
customClaims := jwt.MapClaims{ customClaims := jwt.MapClaims{
"iss": hostName, "iss": hostName,
"aud": memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID), "aud": clientID,
"nonce": nonce, "nonce": nonce,
"sub": user.ID, "sub": user.ID,
"exp": expiresAt, "exp": expiresAt,
@ -285,7 +297,11 @@ func ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionD
// CreateIDToken util to create JWT token, based on // CreateIDToken util to create JWT token, based on
// user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT // user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT
func CreateIDToken(user models.User, roles []string, hostname, nonce string) (string, int64, error) { 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 { if err != nil {
expiryBound = time.Minute * 30 expiryBound = time.Minute * 30
} }
@ -297,10 +313,18 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce string) (st
var userMap map[string]interface{} var userMap map[string]interface{}
json.Unmarshal(userBytes, &userMap) 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{ customClaims := jwt.MapClaims{
"iss": hostname, "iss": hostname,
"aud": memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID), "aud": clientID,
"nonce": nonce, "nonce": nonce,
"sub": user.ID, "sub": user.ID,
"exp": expiresAt, "exp": expiresAt,
@ -317,7 +341,11 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce string) (st
} }
// check for the extra access token script // 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 != "" { if accessTokenScript != "" {
vm := otto.New() vm := otto.New()

View File

@ -11,7 +11,10 @@ import (
// SignJWTToken common util to sing jwt token // SignJWTToken common util to sing jwt token
func SignJWTToken(claims jwt.MapClaims) (string, error) { 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) signingMethod := jwt.GetSigningMethod(jwtType)
if signingMethod == nil { if signingMethod == nil {
return "", errors.New("unsupported signing method") return "", errors.New("unsupported signing method")
@ -24,15 +27,27 @@ func SignJWTToken(claims jwt.MapClaims) (string, error) {
switch signingMethod { switch signingMethod {
case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512: 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: 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 { if err != nil {
return "", err return "", err
} }
return t.SignedString(key) return t.SignedString(key)
case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512: 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 { if err != nil {
return "", err return "", err
} }
@ -45,20 +60,30 @@ func SignJWTToken(claims jwt.MapClaims) (string, error) {
// ParseJWTToken common util to parse jwt token // ParseJWTToken common util to parse jwt token
func ParseJWTToken(token, hostname, nonce, subject string) (jwt.MapClaims, error) { 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) signingMethod := jwt.GetSigningMethod(jwtType)
var err error
var claims jwt.MapClaims var claims jwt.MapClaims
switch signingMethod { switch signingMethod {
case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512: case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512:
_, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { _, 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: case jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512:
_, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { _, 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 { if err != nil {
return nil, err return nil, err
} }
@ -66,7 +91,11 @@ func ParseJWTToken(token, hostname, nonce, subject string) (jwt.MapClaims, error
}) })
case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512: case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512:
_, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { _, 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 { if err != nil {
return nil, err return nil, err
} }
@ -86,8 +115,11 @@ func ParseJWTToken(token, hostname, nonce, subject string) (jwt.MapClaims, error
intIat := int64(claims["iat"].(float64)) intIat := int64(claims["iat"].(float64))
claims["exp"] = intExp claims["exp"] = intExp
claims["iat"] = intIat claims["iat"] = intIat
clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
if claims["aud"] != memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID) { if err != nil {
return claims, err
}
if claims["aud"] != clientID {
return claims, errors.New("invalid audience") 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 // ParseJWTTokenWithoutNonce common util to parse jwt token without nonce
// used to validate ID token as it is not persisted in store // used to validate ID token as it is not persisted in store
func ParseJWTTokenWithoutNonce(token, hostname string) (jwt.MapClaims, error) { 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) signingMethod := jwt.GetSigningMethod(jwtType)
var err error
var claims jwt.MapClaims var claims jwt.MapClaims
switch signingMethod { switch signingMethod {
case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512: case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512:
_, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { _, 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: case jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512:
_, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { _, 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 { if err != nil {
return nil, err return nil, err
} }
@ -130,7 +172,11 @@ func ParseJWTTokenWithoutNonce(token, hostname string) (jwt.MapClaims, error) {
}) })
case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512: case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512:
_, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) { _, 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 { if err != nil {
return nil, err return nil, err
} }
@ -150,8 +196,11 @@ func ParseJWTTokenWithoutNonce(token, hostname string) (jwt.MapClaims, error) {
intIat := int64(claims["iat"].(float64)) intIat := int64(claims["iat"].(float64))
claims["exp"] = intExp claims["exp"] = intExp
claims["iat"] = intIat claims["iat"] = intIat
clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
if claims["aud"] != memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID) { if err != nil {
return claims, err
}
if claims["aud"] != clientID {
return claims, errors.New("invalid audience") return claims, errors.New("invalid audience")
} }

View File

@ -10,9 +10,13 @@ import (
// CreateVerificationToken creates a verification JWT token // CreateVerificationToken creates a verification JWT token
func CreateVerificationToken(email, tokenType, hostname, nonceHash, redirectURL string) (string, error) { 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{ claims := jwt.MapClaims{
"iss": hostname, "iss": hostname,
"aud": memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID), "aud": clientID,
"sub": email, "sub": email,
"exp": time.Now().Add(time.Minute * 30).Unix(), "exp": time.Now().Add(time.Minute * 30).Unix(),
"iat": time.Now().Unix(), "iat": time.Now().Unix(),