This commit is contained in:
Aaron Po
2026-08-31 18:33:20 -04:00
parent 30995f6f40
commit 772a65d896
11 changed files with 353 additions and 218 deletions

View File

@@ -1,4 +1,12 @@
# Token validation architecture
---
title: JWT token validation architecture
last-updated: 2026-08-31
tags:
- jwt
- authentication
- security
- tokens
---
## Overview
@@ -64,10 +72,9 @@ Token generation and validation live on the same slice-internal service.
`TokenService` is registered by `Features.Users`' own `AddFeaturesUsers()`
extension method, except for the lower-level `ITokenInfrastructure` (JWT
signing/verification) it
depends on, which is registered by the host (`API.Core/Program.cs`) since
`JwtAuthenticationHandler` (host-level auth middleware) also depends on it
directly.
signing/verification) it depends on, which is registered by the host
(`API.Core/Program.cs`) since `JwtAuthenticationHandler` (host-level auth
middleware) also depends on it directly.
### Integration points
@@ -77,14 +84,16 @@ directly.
1. Receives confirmation token from user via `ConfirmUserCommand`
2. Calls `ITokenService.ValidateConfirmationTokenAsync()`
3. Extracts user ID from validated token and looks it up via `UserManager<ApplicationUser>`
4. Marks the account confirmed via `IUserEmailStore<ApplicationUser>.SetEmailConfirmedAsync()`,
then persists it via `UserManager<ApplicationUser>.UpdateAsync()`
3. Extracts user ID from validated token and looks it up via
`UserManager<ApplicationUser>`
4. Marks the account confirmed via
`IUserEmailStore<ApplicationUser>.SetEmailConfirmedAsync()`, then persists it
via `UserManager<ApplicationUser>.UpdateAsync()`
5. Returns confirmation result
`UserManager<ApplicationUser>` and `IUserEmailStore<ApplicationUser>` are
ASP.NET Core Identity's abstractions, not EF Core's default Identity store:
the app backs them with its own `DapperUserStore` (see
ASP.NET Core Identity's abstractions, not EF Core's default Identity store: the
app backs them with its own `DapperUserStore` (see
[Database](database.md#database-error-handling)), which persists against the
existing `UserAccount`/`UserCredential`/`UserVerification` tables via Dapper,
consistent with the rest of the app's repository pattern.