Skip to content

Commit

Permalink
fix: check server side session for REST API endpoints (#1988)
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 authored Dec 5, 2024
1 parent 4580c6a commit d510fa5
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 d510fa5

Please sign in to comment.