fix: openid flow
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package token
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
@@ -46,28 +48,22 @@ type SessionData struct {
|
||||
LoginMethod string `json:"login_method"`
|
||||
}
|
||||
|
||||
// CreateSessionToken creates a new session token
|
||||
func CreateSessionToken(user models.User, nonce string, roles, scope []string, loginMethod string) (*SessionData, string, error) {
|
||||
fingerPrintMap := &SessionData{
|
||||
Nonce: nonce,
|
||||
Roles: roles,
|
||||
Subject: user.ID,
|
||||
Scope: scope,
|
||||
LoginMethod: loginMethod,
|
||||
IssuedAt: time.Now().Unix(),
|
||||
ExpiresAt: time.Now().AddDate(1, 0, 0).Unix(),
|
||||
}
|
||||
fingerPrintBytes, _ := json.Marshal(fingerPrintMap)
|
||||
fingerPrintHash, err := crypto.EncryptAES(string(fingerPrintBytes))
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return fingerPrintMap, fingerPrintHash, nil
|
||||
}
|
||||
|
||||
// CreateAuthToken creates a new auth token when userlogs in
|
||||
func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, loginMethod, nonce string) (*Token, error) {
|
||||
|
||||
code := ""
|
||||
nonceSplit := strings.Split(nonce, "@@")
|
||||
fingerPrint := nonce
|
||||
fmt.Println("=> nonce split", nonceSplit)
|
||||
if len(nonceSplit) > 1 {
|
||||
code = nonceSplit[1]
|
||||
// use original nonce for session token and access token
|
||||
nonce = nonceSplit[0]
|
||||
fingerPrint = nonce
|
||||
}
|
||||
|
||||
fmt.Println("=> original nonce:", nonce)
|
||||
|
||||
hostname := parsers.GetHost(gc)
|
||||
_, fingerPrintHash, err := CreateSessionToken(user, nonce, roles, scope, loginMethod)
|
||||
if err != nil {
|
||||
@@ -78,13 +74,31 @@ func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, l
|
||||
return nil, err
|
||||
}
|
||||
|
||||
idToken, idTokenExpiresAt, err := CreateIDToken(user, roles, hostname, nonce, loginMethod)
|
||||
atHash := sha256.New()
|
||||
atHash.Write([]byte(accessToken))
|
||||
atHashBytes := atHash.Sum(nil)
|
||||
// hashedToken := string(bs)
|
||||
atHashDigest := atHashBytes[0 : len(atHashBytes)/2]
|
||||
atHashString := base64.RawURLEncoding.EncodeToString(atHashDigest)
|
||||
|
||||
codeHashString := ""
|
||||
if code != "" {
|
||||
fmt.Println("=> atHash", atHashString)
|
||||
codeHash := sha256.New()
|
||||
codeHash.Write([]byte(code))
|
||||
codeHashBytes := codeHash.Sum(nil)
|
||||
codeHashDigest := codeHashBytes[0 : len(codeHashBytes)/2]
|
||||
codeHashString = base64.RawURLEncoding.EncodeToString(codeHashDigest)
|
||||
}
|
||||
|
||||
fmt.Println("=> at hash nonce", nonce)
|
||||
idToken, idTokenExpiresAt, err := CreateIDToken(user, roles, hostname, nonce, atHashString, codeHashString, loginMethod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := &Token{
|
||||
FingerPrint: nonce,
|
||||
FingerPrint: fingerPrint,
|
||||
FingerPrintHash: fingerPrintHash,
|
||||
AccessToken: &JWTToken{Token: accessToken, ExpiresAt: accessTokenExpiresAt},
|
||||
IDToken: &JWTToken{Token: idToken, ExpiresAt: idTokenExpiresAt},
|
||||
@@ -102,6 +116,27 @@ func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, l
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// CreateSessionToken creates a new session token
|
||||
func CreateSessionToken(user models.User, nonce string, roles, scope []string, loginMethod string) (*SessionData, string, error) {
|
||||
fingerPrintMap := &SessionData{
|
||||
Nonce: nonce,
|
||||
Roles: roles,
|
||||
Subject: user.ID,
|
||||
Scope: scope,
|
||||
LoginMethod: loginMethod,
|
||||
IssuedAt: time.Now().Unix(),
|
||||
ExpiresAt: time.Now().AddDate(1, 0, 0).Unix(),
|
||||
}
|
||||
fmt.Printf("=> session data %+v\n", fingerPrintMap)
|
||||
fingerPrintBytes, _ := json.Marshal(fingerPrintMap)
|
||||
fingerPrintHash, err := crypto.EncryptAES(string(fingerPrintBytes))
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return fingerPrintMap, fingerPrintHash, nil
|
||||
}
|
||||
|
||||
// CreateRefreshToken util to create JWT token
|
||||
func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonce, loginMethod string) (string, int64, error) {
|
||||
// expires in 1 year
|
||||
@@ -318,7 +353,7 @@ func ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionD
|
||||
// user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT
|
||||
// For response_type (code) / authorization_code grant nonce should be empty
|
||||
// for implicit flow it should be present to verify with actual state
|
||||
func CreateIDToken(user models.User, roles []string, hostname, nonce, loginMethod string) (string, int64, error) {
|
||||
func CreateIDToken(user models.User, roles []string, hostname, nonce, atHash, cHash, loginMethod string) (string, int64, error) {
|
||||
expireTime, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime)
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
@@ -344,10 +379,10 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce, loginMetho
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
|
||||
customClaims := jwt.MapClaims{
|
||||
"iss": hostname,
|
||||
"aud": clientID,
|
||||
// "nonce": nonce,
|
||||
"iss": hostname,
|
||||
"aud": clientID,
|
||||
"sub": user.ID,
|
||||
"exp": expiresAt,
|
||||
"iat": time.Now().Unix(),
|
||||
@@ -357,6 +392,20 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce, loginMetho
|
||||
claimKey: roles,
|
||||
}
|
||||
|
||||
fmt.Println("=> nonce", nonce)
|
||||
|
||||
// split nonce to see if its authorization code grant method
|
||||
|
||||
if cHash != "" {
|
||||
customClaims["at_hash"] = atHash
|
||||
customClaims["c_hash"] = cHash
|
||||
} else {
|
||||
customClaims["nonce"] = nonce
|
||||
customClaims["at_hash"] = atHash
|
||||
}
|
||||
|
||||
fmt.Println("custom_claims", customClaims)
|
||||
|
||||
for k, v := range userMap {
|
||||
if k != "roles" {
|
||||
customClaims[k] = v
|
||||
|
Reference in New Issue
Block a user