Skip to content

IDN-02 (3/5): US-04 US-05 US-06 login, logout and session check - #63

Open
milanPR15 wants to merge 1 commit into
feature/US-02-US-03-US-09-identity-storefrom
feature/US-04-US-05-US-06-login-logout-session
Open

milanPR15 wants to merge 1 commit into
feature/US-02-US-03-US-09-identity-storefrom
feature/US-04-US-05-US-06-login-logout-session

Conversation

@milanPR15

@milanPR15 milanPR15 commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Part 3 of 5 of IDN-02, split from #55. Base: part 2. Review and merge in order 1 → 5, without squash.

Component and requirement IDs

  • Component: Identity (Team 1, IDN-02)
  • Requirements: IDN-02 (primary), ACC-05, SEC-01, SEC-03, AUD-03
  • Stories: US-04 (login), US-05 (logout), US-06 (session check on every request)
  • Author(s): Milan Stojanovic, with marijanamijic, didi40904, Nole, Denis Đuriš, Dobi04 and lmilanal (co-authors in the commit)

Changes

Size: 42 files, +1645 / −792. About 1100 lines of tests and 540 lines of code; the deletions are replaced placeholders.

  • US-04: POST /api/auth/login (AuthController, LoginService, StoreSessionCreator). Every login creates a new session, and the token travels only in an HttpOnly, Secure, SameSite=Strict cookie, never in the body. Wrong password, unknown account and a blocked or archived account get the same response; only the audit event records the reason.
  • US-05: POST /api/auth/logout (LogoutService) revokes the session in the store and deletes the cookie. It is idempotent and leaves the user's other sessions valid.
  • US-06: SessionCheckMiddleware validates the cookie against the store on every request to an endpoint without [AllowAnonymous], and returns 401 without details for a missing, unknown, expired or revoked session (ACC-05). SessionIdentityContext exposes the caller through IIdentityContext, and GET /api/auth/me returns the user without secrets.
  • Contract: ISessionManager becomes the async contract backed by the session store. It replaces the IDN-02 placeholders and Development stubs that reached main in Feature/idn 03 account status #33: LoginController, LoginAccount, LoginAdapters, ICredentialAuthenticator, ISessionIssuer, the IDN-03 SessionValidationMiddleware, and the always-active and no-op session stubs.

Effect on other modules

  • The middleware applies to the whole API. In Development, routes of other modules that authenticate callers themselves or are anonymous demos are let through: /api/laboratories, /api/kt1 and /api/access/demo-deny. Outside Development, these routes and every new endpoint without [AllowAnonymous] need an IDN-02 session.
  • Platform.Identity.Tests/Services/ChangeAccountStatusTests.cs (IDN-03): its fake implements the new ISessionManager. The five IsSessionActive_* tests that only checked that fake are removed, and the status-change tests are unchanged.
  • Platform.Kt1.Tests/MainCompositionTests.cs (ACC-04/ADM-08, Bojana Kovacic): the X-Stub-User header no longer authenticates the IDN-03 administrator, because the IDN-02 session replaces that Development stub. The test now expects 401 and an unchanged status. Owner confirmation needed.

Verification

  • Build: 0 errors, 0 warnings.
  • dotnet test backend/SecurityLab.slnx -c Release: all pass. Identity 182, Kt1 65, Audit 95, Authoring 55, Laboratories 31, Platform.Tests 28, RateLimiting 24, LabMetadata 7.
  • CI step "Live KT1 demonstration" (scripts/kt1-demo.ps1), run locally: 41/41 PASS.

Architecture and data flow

Processes P1 (login), P3 (session check) and P4 (logout) of the IDN-02 DFD. The diagrams are in part 5.

Security checks and negative tests

The old cookie after logout returns 401, and so do a revoked session, an expired session, an unknown token and a missing cookie. A second logout writes no second audit event. Audit events never contain the token or its hash. Middleware tests cover the Development-only exemptions both ways: allowed in Development, 401 outside it and for look-alike paths.

Dependencies

  • Base: part 2. Next: part 4.
  • Known follow-ups owned by other stories: CSRF (US-15), session expiry rules (US-14), audit of rejected session checks (US-23), and connecting the IDN-03 account status to the login database (US-27).

Stack

  1. IDN-02 (1/5): group identity code by kind folders (moves only) #61 group identity code by kind folders (moves only), base main
  2. IDN-02 (2/5): US-02 US-03 US-09 identity database, session store and seed #62 identity database, session store and seed (US-02, US-03, US-09)
  3. IDN-02 (3/5): US-04 US-05 US-06 login, logout and session check #63 login, logout and session check (US-04, US-05, US-06)
  4. IDN-02 (4/5): US-07 US-08 frontend login, protected routes and logout #64 frontend login, protected routes and logout (US-07, US-08)
  5. IDN-02 (5/5): US-01 US-10 US-11 contracts, DFD, architecture and run instructions #65 contracts, DFD, architecture and run instructions (US-01, US-10, US-11)

Replaces #55.

🤖 Generated with Claude Code

…on check

- US-04: POST /api/auth/login verifies the credentials and creates a new
  server-side session; the token travels only in an HttpOnly, Secure,
  SameSite cookie. Wrong password, unknown account and a blocked or archived
  account get the same response; only the audit event records the reason.
- US-05: POST /api/auth/logout revokes the session in the store and deletes
  the cookie; it is idempotent and leaves the user's other sessions alone.
- US-06: SessionCheckMiddleware validates the cookie against the store on
  every request to an endpoint without [AllowAnonymous] and answers 401 for a
  missing, unknown, expired or revoked session (ACC-05). Development-only
  routes of other modules that authenticate callers themselves
  (/api/laboratories, /api/kt1, /api/access/demo-deny) are let through.
  SessionIdentityContext exposes the caller through IIdentityContext, and
  GET /api/auth/me returns the current user without secrets.
- ISessionManager becomes the async contract backed by the session store and
  replaces the IDN-02 placeholders and Development stubs that reached main in
  #33 (LoginController, LoginAccount, ICredentialAuthenticator, ISessionIssuer,
  SessionValidationMiddleware and the always-active session stubs).
- The IDN-03 status test uses the new contract in its fake, and the KT1
  composition test now expects 401 for the X-Stub-User header.

Co-authored-by: marijanamijic <marijana.mijic@toppandigital.com>
Co-authored-by: didi40904 <116975925+didi40904@users.noreply.github.com>
Co-authored-by: Nole <daki.nole@gmail.com>
Co-authored-by: Denis Đuriš <135664071+Duro375@users.noreply.github.com>
Co-authored-by: Dobi04 <nj675896@gmail.com>
Co-authored-by: lmilanal <lazic.pr141.2023@uns.ac.rs>
Co-Authored-By: Claude Opus 5.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.

1 participant