Module Audit
Module de tracabilite automatique - middleware HTTP, behavior MediatR, SignalR et persistance
Module Audit
Le module Audit assure la tracabilite complete de toutes les actions effectuees dans l'API. Il collecte les evenements d'audit depuis deux sources (middleware HTTP et behavior MediatR), les persiste en base de donnees et les diffuse en temps reel via SignalR.
Architecture du module
Sources d'evenements d'audit
AuditHttpMiddleware (BuildingBlocks)
Le middleware HTTP intercepte toutes les requetes entrantes et produit un evenement d'audit contenant :
- Methode et route :
GET,POST, etc. avec le template de route - Codes de reponse : classification automatique (Success, Failure, Denied, Noop)
- Corps de requete/reponse : capture optionnelle avec tronquage configurable
- Duree de traitement : en millisecondes
- Contexte : IP, User-Agent, correlation ID, trace ID, span ID
- Classification : Activity, Security (401/403), Exception (500+)
Le middleware est configurable via AuditHttpMiddlewareOptions :
Enabled: activer/desactiver le middlewareCaptureBodies: capturer les corps de requete/reponseMaxBodyBytes: taille maximale des corps capturesExcludedPaths: chemins exclus de l'audit (health checks, swagger, etc.)AllowedContentTypes: types MIME autorises pour la capture de corps
AuditCommandBehavior (BuildingBlocks)
Le behavior MediatR intercepte toutes les commandes (ICommand<T>) et produit un evenement d'audit :
- Seules les commandes sont auditees (pas les queries)
- Les commandes avec l'attribut
[SkipAudit]sont ignorees - Le nom d'action est derive du nom de la commande (
LoginCommand->login) - Le nom du module est infere depuis le namespace
- L'ID d'entite est extrait automatiquement depuis les proprietes
Idou*Id - En cas d'echec, l'exception est capturee sans interrompre sa propagation
Entite AuditLog
L'entite principale du module, persistee dans le schema audit :
| Propriete | Type | Description |
|---|---|---|
Id | Guid | Identifiant unique de l'evenement |
OccurredAtUtc | DateTime | Moment ou l'action s'est produite |
ReceivedAtUtc | DateTime | Moment de reception par le module |
ModuleName | string | Module source (identity, messaging, http) |
ActionName | string | Nom de l'action (login, register, http.post.api.v1.identity.auth.login) |
EventType | string | Type (activity, security, exception) |
EntityType | string | Type d'entite affectee |
EntityId | string | Identifiant de l'entite |
ActorUserId | Guid? | Utilisateur qui a effectue l'action |
ActorType | string? | Type d'acteur (user, system) |
Result | string | Resultat (success, failure, denied, noop) |
Reason | string? | Raison en cas d'echec |
Severity | string | Severite (business, security, infrastructure) |
TenantId | string? | Identifiant du tenant |
IpAddress | string? | Adresse IP source |
UserAgent | string? | User-Agent du client |
CorrelationId | string? | Identifiant de correlation |
RequestId | string? | Identifiant de requete |
TraceId | string? | Trace ID OpenTelemetry |
SpanId | string? | Span ID OpenTelemetry |
Tags | string[] | Tags (authentication, authorization) |
MetadataJson | string | Metadonnees JSON (methode HTTP, status code, duree, etc.) |
TokenFingerprintSha256 | string? | Empreinte du token JWT |
Source | string | Source de l'evenement (command, http, system) |
PayloadJson | string | Payload JSON (corps de requete/reponse, parametres de commande) |
Version | int | Version du format d'evenement |
Services
IAuditLogWriter / AuditLogWriter
Service responsable de la persistance et de la diffusion des evenements :
public interface IAuditLogWriter
{
Task WriteAsync(AuditEventV1 auditEvent, CancellationToken cancellationToken);
}
L'implementation AuditLogWriter :
- Convertit l'
AuditEventV1en entiteAuditLog - Persiste en base via
AuditContext - Enregistre les metriques (evenement persiste, echec, latence)
- Diffuse le log via SignalR vers le groupe
audit-admins
En cas d'echec de la diffusion SignalR, un warning est logue mais l'evenement est deja persiste.
AuditHub (SignalR)
Hub SignalR pour la diffusion en temps reel des evenements d'audit :
- Route :
/hubs/audit - Autorisation :
[Authorize]- seuls les utilisateurs avec le roleAdminpeuvent se connecter - Groupe :
audit-admins - Evenement :
AuditLogInserted- envoye a chaque nouvel evenement d'audit
[Authorize]
internal sealed class AuditHub(ILogger<AuditHub> logger) : Hub
{
public override async Task OnConnectedAsync()
{
bool isAdmin = Context.User?.IsInRole(IdentityConstant.Role.Admin) ?? false;
if (!isAdmin)
{
Context.Abort();
return;
}
await Groups.AddToGroupAsync(Context.ConnectionId, GroupName);
}
}
Configuration SignalR :
MaximumReceiveMessageSize: 16 KoMaximumParallelInvocationsPerClient: 1ClientTimeoutInterval: 60 secondesKeepAliveInterval: 15 secondes
Features d'administration
| Feature | Type | Description |
|---|---|---|
| GetAuditLogs | Query | Liste paginee des logs d'audit |
| GetAuditLogById | Query | Detail d'un log par ID |
| GetAuditLogsByCorrelation | Query | Logs par correlation ID |
| GetAuditLogsByTrace | Query | Logs par trace ID OpenTelemetry |
| GetAuditSummary | Query | Resume statistique des evenements |
| GetExceptionAuditLogs | Query | Logs de type exception uniquement |
| GetSecurityAuditLogs | Query | Logs de type securite uniquement |
| ConsumeAuditEvent | Handler | Consommation des notifications MediatR |
DbContext
public sealed class AuditContext : AppDbContextBase
{
public DbSet<AuditLog> AuditLogs => Set<AuditLog>();
protected override void OnModelCreating(ModelBuilder builder)
{
builder.ApplyConfigurationsFromAssembly(typeof(AuditContext).Assembly);
builder.ToSnakeCaseTables();
}
}
Le schema utilise la convention snake_case pour les noms de tables et colonnes.
Metriques
Le module expose des metriques OpenTelemetry via AuditMetrics :
audit.event.persisted: nombre d'evenements persistes avec succesaudit.event.failed: nombre d'echecs de persistanceaudit.write.latency: latence d'ecriture en millisecondesaudit.http.body.capture.skipped: nombre de captures de corps ignorees
Infrastructure partagee (BuildingBlocks/Auditing)
Le dossier BuildingBlocks/Auditing/ contient toute l'infrastructure d'audit reutilisable :
| Composant | Description |
|---|---|
AuditEventV1 | Record immutable representant un evenement d'audit |
AuditHttpMiddleware | Middleware ASP.NET Core pour l'audit HTTP |
AuditCommandBehavior | Pipeline behavior MediatR pour l'audit des commandes |
AuditEmitter / IAuditEmitter | Emission des evenements via MediatR |
AuditContext / IAuditContextProvider | Fournisseur du contexte d'execution |
AuditSeverityClassifier | Classification de la severite |
AuditMaskingService | Masquage des donnees sensibles |
AuditMetrics | Metriques OpenTelemetry |
AuditActionAttribute | Attribut pour nommer les actions |
SkipAuditAttribute | Attribut pour exclure de l'audit |
EntityChangeAuditSaveChangesInterceptor | Intercepteur EF Core pour les changements d'entites |
TokenFingerprintProvider | Extraction de l'empreinte du token JWT |
| Enums | ActivityKind, AuditActorType, AuditEventType, AuditLevel, AuditResult, AuditTag, SecurityAction |