Skip to content

Commit

Permalink
fix: check server side session for REST API endpoints
Browse files Browse the repository at this point in the history
Check server side sessions in session middleware for REST API endpoints.
Without it a server side session could be deleted, but can still be used at the REST API endpoints.
  • Loading branch information
FreddyDevelop committed Dec 4, 2024
1 parent 2cf5b3d commit 692c369
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
2 changes: 1 addition & 1 deletion backend/handler/public_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func NewPublicRouter(cfg *config.Config, persister persistence.Persister, promet
saml.CreateSamlRoutes(e, sessionManager, auditLogger, samlService)
}

sessionMiddleware := hankoMiddleware.Session(cfg, sessionManager)
sessionMiddleware := hankoMiddleware.Session(cfg, persister, sessionManager)

webhookMiddleware := hankoMiddleware.WebhookMiddleware(cfg, jwkManager, persister)

Expand Down
44 changes: 40 additions & 4 deletions backend/middleware/session.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
package middleware

import (
"errors"
"fmt"
"github.com/gofrs/uuid"
echojwt "github.com/labstack/echo-jwt/v4"
"github.com/labstack/echo/v4"
"github.com/teamhanko/hanko/backend/config"
"github.com/teamhanko/hanko/backend/persistence"
"github.com/teamhanko/hanko/backend/session"
"net/http"
"time"
)

// Session is a convenience function to create a middleware.JWT with custom JWT verification
func Session(cfg *config.Config, generator session.Manager) echo.MiddlewareFunc {
func Session(cfg *config.Config, persister persistence.Persister, generator session.Manager) echo.MiddlewareFunc {
c := echojwt.Config{
ContextKey: "session",
TokenLookup: fmt.Sprintf("header:Authorization:Bearer,cookie:%s", cfg.Session.Cookie.GetName()),
ParseTokenFunc: parseToken(generator),
ParseTokenFunc: parseToken(cfg.Session, persister, generator),
ErrorHandler: func(c echo.Context, err error) error {
return echo.NewHTTPError(http.StatusUnauthorized).SetInternal(err)
},
Expand All @@ -24,8 +28,40 @@ func Session(cfg *config.Config, generator session.Manager) echo.MiddlewareFunc

type ParseTokenFunc = func(c echo.Context, auth string) (interface{}, error)

func parseToken(generator session.Manager) ParseTokenFunc {
func parseToken(cfg config.Session, persister persistence.Persister, generator session.Manager) ParseTokenFunc {
return func(c echo.Context, auth string) (interface{}, error) {
return generator.Verify(auth)
token, err := generator.Verify(auth)
if err != nil {
return nil, err
}

if cfg.ServerSide.Enabled {
// check that the session id is stored in the database
sessionId, ok := token.Get("session_id")
if !ok {
return nil, errors.New("no session id found in token")
}
sessionID, err := uuid.FromString(sessionId.(string))
if err != nil {
return nil, errors.New("session id has wrong format")
}

sessionModel, err := persister.GetSessionPersister().Get(sessionID)
if err != nil {
return nil, fmt.Errorf("failed to get session from database: %w", err)
}
if sessionModel == nil {
return nil, fmt.Errorf("session id not found in database")
}

// Update lastUsed field
sessionModel.LastUsed = time.Now().UTC()
err = persister.GetSessionPersister().Update(*sessionModel)
if err != nil {
return nil, err
}
}

return token, nil
}
}

0 comments on commit 692c369

Please sign in to comment.