Infrastructure
Composants techniques transversaux - JWT, sessions, OTP, rate limiting, metriques et DbContext
Infrastructure
Configuration JWT
JwtOptions
Defini dans Identity.Infrastructure.Auth.Options.JwtOptions :
| Option | Description |
|---|---|
PrivateKeyBase64 | Cle privee RSA en Base64 pour la signature des tokens |
Issuer | Emetteur du token (JWT_ISSUER) |
Audience | Audience cible (JWT_AUDIENCE) |
AccessTokenLifetimeMinutes | Duree de vie de l'access token en minutes |
Valide au demarrage via JwtOptionsValidator.
TokenService
Implementation de ITokenService dans Identity.Infrastructure.Services.TokenService :
- Signe les access tokens avec RSA (algorithme RS256)
- Les refresh tokens sont des chaines aleatoires de 64 octets encodees en Base64
- Les refresh tokens sont hashes avec HMAC-SHA256 + un pepper secret avant stockage
ClaimsBuilder
Identity.Infrastructure.Services.ClaimsBuilder construit les claims JWT :
sub: identifiant utilisateuremail: adresse emailrole: roles (multiples claims si plusieurs roles)sid: identifiant de session- Claims personnalises (permissions, groupes)
JWKS Endpoint
L'endpoint /api/v1/identity/auth/.well-known/jwks.json expose les cles publiques RSA au format JWKS, permettant aux services externes de verifier les tokens sans partager la cle privee.
ProblemDetailsJwtEvents
Gestion personnalisee des erreurs JWT (401, 403) avec format ProblemDetails RFC 7807.
Gestion des sessions
SessionOptions
Defini dans Identity.Infrastructure.Auth.Options.SessionOptions :
| Option | Description |
|---|---|
RefreshTokenLifetimeDays | Duree de vie du refresh token en jours |
MaxActiveSessions | Nombre maximum de sessions actives par utilisateur |
EnforceSessionBinding | Verifier l'IP et le DeviceId a chaque refresh |
Valide au demarrage via SessionOptionsValidator.
SessionService
Implementation combinee de ISessionReader, ISessionWriter et ISessionCleanup :
- Creation : genere une session avec les informations de l'appareil, le hash du refresh token et la famille de tokens
- Rotation : met a jour le hash du refresh token, conserve l'ancien hash pour la detection de replay
- Revocation : marque une session comme revoquee avec une raison
- Revocation par famille : revoque toutes les sessions d'une famille de tokens (en cas de replay detecte)
- Nettoyage : supprime les sessions expirees (execute periodiquement)
Services de nettoyage (HostedServices)
| Service | Description |
|---|---|
SessionCleanupHostedService | Nettoyage periodique des sessions expirees |
IdempotencyCleanupHostedService | Nettoyage des enregistrements d'idempotence expires |
TwoFactorChallengeCleanupHostedService | Nettoyage des challenges 2FA expires |
PushTokenCleanupHostedService | Nettoyage des push tokens orphelins |
SessionDeviceBindingBootstrapHostedService | Migration des sessions sans DeviceId |
OTP
OtpOptions
Defini dans Identity.Infrastructure.Auth.Options.OtpOptions :
| Option | Description |
|---|---|
Length | Longueur du code OTP (defaut: 6 chiffres) |
ExpiryMinutes | Duree de validite en minutes |
MaxAttempts | Nombre maximum de tentatives |
OtpService
Implementation de IOtpService dans Identity.Infrastructure.Services.OtpService :
- Genere un code numerique aleatoire de longueur configurable
- Hash le code avant stockage dans
OtpRecord - Valide en comparant le hash avec limitation du nombre de tentatives
- Marque le code comme utilise apres validation reussie
Authentification sociale
SocialAuthOptions
Configuration des providers sociaux :
| Provider | Options |
|---|---|
ClientId | |
AppId, AppSecret | |
| Apple | ClientId, KeyId, TeamId |
Validateurs de tokens
| Validateur | Description |
|---|---|
GoogleTokenValidator | Valide les ID tokens Google via Google.Apis.Auth |
FacebookTokenValidator | Valide les access tokens Facebook via l'API Graph |
AppleTokenValidator | Valide les ID tokens Apple via les cles publiques Apple |
ProviderLinkingService
Gestion de la liaison de comptes sociaux a un compte existant :
- Verifie qu'un provider n'est pas deja lie a un autre compte
- Cree un
UserLoginavec leProviderEmailet la date de liaison
Rate Limiting
RateLimitingOptions
Configuration des politiques de rate limiting :
public class RateLimitingOptions
{
public PolicyOptions Global { get; set; }
public PolicyOptions Registration { get; set; }
public PolicyOptions Auth { get; set; }
public PolicyOptions SessionsRead { get; set; }
public PolicyOptions SessionsRevoke { get; set; }
public PolicyOptions AdminSessions { get; set; }
public PolicyOptions TwoFactor { get; set; }
}
public class PolicyOptions
{
public int PermitLimit { get; set; }
public int WindowSeconds { get; set; }
public int QueueLimit { get; set; }
}
RateLimitPartitionKeyBuilder
Construction des cles de partition pour le rate limiting :
- Anonyme : partition par adresse IP
- Authentifie : partition par identifiant utilisateur
RateLimitHeaderWriter
Ecrit les en-tetes standard de rate limiting dans les reponses HTTP :
X-RateLimit-Limit: limite de requetesX-RateLimit-Remaining: requetes restantesX-RateLimit-Reset: timestamp de reinitialisationRetry-After: delai avant de reessayer (en cas de 429)
Idempotence
PersistentIdempotencyFilter
Filtre d'endpoint qui assure l'idempotence des requetes POST/PUT :
- Verifie la presence d'une cle d'idempotence dans les en-tetes
- Cherche un enregistrement existant pour cette cle
- Si trouve et non expire : retourne la reponse en cache
- Sinon : execute la requete, persiste la reponse dans
IdempotencyRecord
Metriques et telemetrie
IdentityMetrics
Metriques OpenTelemetry exposees par le module Identity :
| Metrique | Description |
|---|---|
identity.login.success | Nombre de connexions reussies |
identity.login.failure | Echecs de connexion par raison (UserNotFound, InvalidPassword, LockedOut, etc.) |
identity.registration.success | Inscriptions reussies |
identity.registration.failure | Echecs d'inscription par raison |
identity.token.refresh.success | Refresh tokens reussis |
identity.token.refresh.failure | Echecs de refresh par raison (ReplayDetected, SessionExpired, etc.) |
identity.rate_limit.rejected | Requetes rejetees par rate limiting par politique |
AuditMetrics
Metriques du module Audit :
| Metrique | Description |
|---|---|
audit.event.persisted | Evenements persistes |
audit.event.failed | Echecs de persistance |
audit.write.latency | Latence d'ecriture (ms) |
DbContext
IdentityContext
Herite de IdentityDbContext<User, Role, Guid, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>.
DbSets : UserSessions, PasswordHistories, OtpRecords, PushTokens, Groups, GroupRoles, UserGroups, IdempotencyRecords, TwoFactorChallenges, UserSecuritySettings.
Conventions appliquees :
FilterSoftDeletedProperties(): filtrage automatique des entites supprimeesToSnakeCaseTables(): convention snake_caseConvertEnumsToStrings(): enums stockes en strings
Support transactionnel complet avec BeginTransactionAsync, CommitTransactionAsync, RollbackTransactionAsync, et ExecuteTransactionalAsync (avec strategie d'execution).
Gestion automatique du versioning via OnBeforeSaving() qui incremente IVersion.Version pour chaque entite modifiee ou supprimee.
AuditContext
Herite de AppDbContextBase. Schema par defaut non specifie (les configurations definissent les schemas au niveau des tables).
DbSets : AuditLogs.
MessagingContext
Herite de AppDbContextBase. Schema : messaging.
DbSets : SentMessages.
Aspire (Orchestration)
Le projet AppHost orchestre l'ensemble de l'infrastructure en developpement :
// PostgreSQL avec 5 bases de donnees
IResourceBuilder<PostgresServerResource> postgres = builder.AddPostgres("postgres")
.WithImage("postgres", "17");
postgres.AddDatabase("identity");
postgres.AddDatabase("audit");
postgres.AddDatabase("messaging");
postgres.AddDatabase("hangfire");
postgres.AddDatabase("persist-message");
// Mailpit pour les emails en dev
IResourceBuilder<ContainerResource> mailpit = builder.AddContainer("mailpit", "axllent/mailpit");
// API Place
IResourceBuilder<ProjectResource> api = builder.AddProject<Projects.Api>("place-api")
.WithReference(identityDb)
.WithReference(auditDb)
.WithReference(messagingDb)
.WithHttpEndpoint(5000, null, "api-http")
.WithHttpsEndpoint(5001, null, "api-https");
// Admin Web (Bun)
builder.AddExecutable("place-admin-web", "bun", adminWebDirectory, "run", "dev")
.WithReference(api)
.WithHttpEndpoint(5175, 5175, "http");