fix: user session access

This commit is contained in:
Lakhan Samani
2022-06-12 00:27:21 +05:30
parent ac49b5bb70
commit 82a2a42f84
22 changed files with 172 additions and 130 deletions

View File

@@ -117,12 +117,12 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
}
cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(user.ID, authToken.FingerPrintHash, authToken.FingerPrint)
memorystore.Provider.SetUserSession(user.ID, authToken.AccessToken.Token, authToken.FingerPrint)
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(user.ID, authToken.RefreshToken.Token, authToken.FingerPrint)
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token)
}
go db.Provider.AddSession(models.Session{

View File

@@ -41,7 +41,7 @@ func LogoutResolver(ctx context.Context) (*model.Response, error) {
return nil, err
}
memorystore.Provider.DeleteUserSession(sessionData.Subject, fingerprintHash)
memorystore.Provider.DeleteUserSession(sessionData.Subject, sessionData.Nonce)
cookie.DeleteSession(gc)
res := &model.Response{

View File

@@ -8,6 +8,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/graph/model"
@@ -29,7 +30,7 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod
sessionToken, err := cookie.GetSession(gc)
if err != nil {
log.Debug("Failed to get session token", err)
log.Debug("Failed to get session token: ", err)
return res, errors.New("unauthorized")
}
@@ -76,10 +77,7 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod
}
// rollover the session for security
memorystore.Provider.RemoveState(sessionToken)
memorystore.Provider.SetUserSession(user.ID, authToken.FingerPrintHash, authToken.FingerPrint)
memorystore.Provider.SetUserSession(user.ID, authToken.AccessToken.Token, authToken.FingerPrint)
cookie.SetSession(gc, authToken.FingerPrintHash)
go memorystore.Provider.DeleteUserSession(userID, claims.Nonce)
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
if expiresIn <= 0 {
@@ -94,10 +92,13 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod
User: user.AsAPIUser(),
}
cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(user.ID, authToken.RefreshToken.Token, authToken.FingerPrint)
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token)
}
return res, nil
}

View File

@@ -225,15 +225,6 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
return res, err
}
memorystore.Provider.SetUserSession(user.ID, authToken.FingerPrintHash, authToken.FingerPrint)
memorystore.Provider.SetUserSession(user.ID, authToken.AccessToken.Token, authToken.FingerPrint)
if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(user.ID, authToken.RefreshToken.Token, authToken.FingerPrint)
}
cookie.SetSession(gc, authToken.FingerPrintHash)
go db.Provider.AddSession(models.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(gc.Request),
@@ -251,6 +242,15 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
ExpiresIn: &expiresIn,
User: userToReturn,
}
cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token)
}
}
return res, nil

View File

@@ -8,6 +8,7 @@ import (
"github.com/golang-jwt/jwt"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
@@ -29,7 +30,7 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
}
tokenType := params.TokenType
if tokenType != "access_token" && tokenType != "refresh_token" && tokenType != "id_token" {
if tokenType != constants.TokenTypeAccessToken && tokenType != constants.TokenTypeRefreshToken && tokenType != constants.TokenTypeIdentityToken {
log.Debug("Invalid token type: ", tokenType)
return nil, errors.New("invalid token type")
}
@@ -38,39 +39,34 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
var claims jwt.MapClaims
userID := ""
nonce := ""
claims, err = token.ParseJWTToken(params.Token)
if err != nil {
log.Debug("Failed to parse JWT token: ", err)
return nil, err
}
userID = claims["sub"].(string)
// access_token and refresh_token should be validated from session store as well
if tokenType == "access_token" || tokenType == "refresh_token" {
claims, err = token.ParseJWTToken(params.Token)
if err != nil {
log.Debug("Failed to parse JWT token: ", err)
return nil, err
}
userID = claims["sub"].(string)
nonce, err = memorystore.Provider.GetUserSession(userID, params.Token)
if err != nil || nonce == "" {
if tokenType == constants.TokenTypeAccessToken || tokenType == constants.TokenTypeRefreshToken {
nonce = claims["nonce"].(string)
token, err := memorystore.Provider.GetUserSession(userID, tokenType+"_"+claims["nonce"].(string))
if err != nil || token == "" {
log.Debug("Failed to get user session: ", err)
return nil, errors.New("invalid token")
}
} else {
// for ID token just parse jwt
claims, err = token.ParseJWTToken(params.Token)
if err != nil {
log.Debug("Failed to parse JWT token: ", err)
return nil, err
}
userID = claims["sub"].(string)
}
hostname := parsers.GetHost(gc)
// we cannot validate sub and nonce in case of id_token as that token is not persisted in session store
if userID != "" && nonce != "" {
// we cannot validate nonce in case of id_token as that token is not persisted in session store
if nonce != "" {
if ok, err := token.ValidateJWTClaims(claims, hostname, nonce, userID); !ok || err != nil {
log.Debug("Failed to parse jwt token: ", err)
return nil, errors.New("invalid claims")
}
} else {
if ok, err := token.ValidateJWTTokenWithoutNonce(claims, hostname); !ok || err != nil {
if ok, err := token.ValidateJWTTokenWithoutNonce(claims, hostname, userID); !ok || err != nil {
log.Debug("Failed to parse jwt token without nonce: ", err)
return nil, errors.New("invalid claims")
}

View File

@@ -8,6 +8,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/db/models"
@@ -80,15 +81,6 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
return res, err
}
memorystore.Provider.SetUserSession(user.ID, authToken.FingerPrintHash, authToken.FingerPrint)
memorystore.Provider.SetUserSession(user.ID, authToken.AccessToken.Token, authToken.FingerPrint)
if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(user.ID, authToken.RefreshToken.Token, authToken.FingerPrint)
}
cookie.SetSession(gc, authToken.FingerPrintHash)
go db.Provider.AddSession(models.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(gc.Request),
@@ -107,5 +99,14 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
ExpiresIn: &expiresIn,
User: user.AsAPIUser(),
}
cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(user.ID, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token)
}
return res, nil
}