Skip to content

Blocklist a legacy JWT locally once GET legacy-auth/logout ends its session - #507

Open
gamadev1 wants to merge 2 commits into
GamaEdtech:stagingfrom
gamadev1:feature/legacy-auth-logout-blocklist
Open

Blocklist a legacy JWT locally once GET legacy-auth/logout ends its session#507
gamadev1 wants to merge 2 commits into
GamaEdtech:stagingfrom
gamadev1:feature/legacy-auth-logout-blocklist

Conversation

@gamadev1

Copy link
Copy Markdown
Collaborator

Summary

  • Stacked on Add legacy-auth-bridge logout endpoint #505 (feature/legacy-auth-logout), not yet merged to staging — until Add legacy-auth-bridge logout endpoint #505 merges, this diff includes Add legacy-auth-bridge logout endpoint #505's changes too; it'll shrink to just the new commit once Add legacy-auth-bridge logout endpoint #505 lands.
  • GET legacy-auth/logout (Add legacy-auth-bridge logout endpoint #505) proxies gama-api's own logout, but ValidateLegacyJwtAsync only checks signature/issuer/audience/expiry offline — it had no way to know a token was just logged out, so the same JWT kept authenticating against this backend until its own exp naturally lapsed.
  • IdentityService.LegacyLogoutAsync now writes the token (SHA-256-hashed, not raw) to ICacheProvider/Redis on a successful proxy logout, TTL'd to the token's own remaining lifetime.
  • VerifyLegacyTokenAsync (per-request auth) and GenerateTokenByCoreTokenAsync (tokens/old) both check the blocklist right after signature validation. SyncLegacyAuthAsync (login/google) intentionally doesn't — a fresh login token can't already be blocklisted.
  • Docs updated: docs/api/authentication.md, docs/api/endpoints.md, docs/business/identity-and-access.md, PROJECT_SNAPSHOT.md.

Test plan

  • dotnet build on the full solution (done locally, 0 warnings/0 errors)
  • Manually exercise: login via legacy-auth/login, call an authenticated endpoint, call legacy-auth/logout, then retry the same authenticated endpoint with the same token and confirm it's now rejected
  • Confirm tokens/old also rejects a blocklisted token

🤖 Generated with Claude Code

sanaderi and others added 2 commits July 13, 2026 11:13
GET legacy-auth/logout proxies gama-api's own GET /users/logout, relaying
the caller's raw legacy JWT from the Authorization header. Pure passthrough
like register/recovery - this backend never stored the token, so gama-api
is the one actually invalidating the session, closing the gap where
tokens/revoke couldn't touch a legacy-bridge session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ession

ValidateLegacyJwtAsync only checked signature/issuer/audience/expiry, so a
token that gama-api had already logged out kept authenticating against this
backend until its own exp naturally lapsed. LegacyLogoutAsync now records the
token (SHA-256-hashed) in ICacheProvider/Redis on a successful proxy logout,
TTL'd to its remaining lifetime; VerifyLegacyTokenAsync and
GenerateTokenByCoreTokenAsync (tokens/old) both check it after signature
validation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants