Skip to content

OIDC users intermittently logged out: SessionRegenerate stores empty session under concurrent requests (v2.15.1) #23290

@villcabo

Description

@villcabo

Expected behavior

An authenticated OIDC user stays logged in while navigating the UI within the session timeout.

Actual behavior

OIDC users get logged out intermittently (often within seconds of login). The browser ends up holding a session cookie (sid) that points to an empty session in Redis, so every subsequent request resolves to an anonymous security context → 401 → the SPA bounces to login, frequently in a loop.

Root cause analysis

In src/core/session/session.go, SessionRegenerate saves an empty session when the oldsid no longer exists:

if isExist, _ := rp.SessionExist(ctx, oldsid); !isExist {
    err := rp.c.Save(ctx, sid, map[any]any{}, maxlifetime) // empty session persisted
}

Under the real Angular UI (many concurrent XHR per page load + background polling), a concurrent request renames oldsid before this path runs, so the regenerate stores an empty session for the new sid, and that new sid is sent to the browser via Set-Cookie. The user is now anonymous despite a valid-looking cookie.

PR #22882 / #22873 / #22726 only changed the stored empty value (""map[any]any{}) and the lifetime; the empty-session-on-race behavior remains in main.

Evidence

Redis DB0 accumulated 54 empty 23-byte sessions vs 2 real ~4760-byte ones. The affected user's cookie sid existed in Redis with a healthy ~46 min TTL but was 23 bytes (empty). Core logs (log.level: debug): the session works ~13 s after callback, then all requests go unauthorized at once; the same endpoint (/api/v2.0/configurations) returns 200 then 401 seconds later.

Environment

  • Harbor v2.15.1 (the relevant code is also present in main)
  • Auth: OIDC (Keycloak), auto-onboard enabled, external PostgreSQL, embedded redis-photon
  • Single harbor-core replica, behind an external reverse proxy

Steps to reproduce

  1. Configure OIDC auth mode.
  2. Log in and navigate quickly across admin pages that fire many parallel API calls (e.g. project quotas / configuration).
  3. Observe intermittent 401s and empty 23-byte sessions piling up in Redis DB0.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions