Iguga.AuditLogging.EntityFramework
1.1.2
dotnet add package Iguga.AuditLogging.EntityFramework --version 1.1.2
NuGet\Install-Package Iguga.AuditLogging.EntityFramework -Version 1.1.2
<PackageReference Include="Iguga.AuditLogging.EntityFramework" Version="1.1.2" />
paket add Iguga.AuditLogging.EntityFramework --version 1.1.2
#r "nuget: Iguga.AuditLogging.EntityFramework, 1.1.2"
// Install Iguga.AuditLogging.EntityFramework as a Cake Addin #addin nuget:?package=Iguga.AuditLogging.EntityFramework&version=1.1.2 // Install Iguga.AuditLogging.EntityFramework as a Cake Tool #tool nuget:?package=Iguga.AuditLogging.EntityFramework&version=1.1.2
🕊️ Iguga.AuditLogging
Simple audit logging for .NET Core with EntityFramework Core support
This project is a fork of Skoruba AuditLoggig ported to .NET 6. 🚀
How to install
dotnet add package Iguga.AuditLogging.EntityFramework --version 1.1.2
How to use it
Setup for web application and auditing of users:
services.AddAuditLogging(options =>
{
options.Enabled = true;
options.UseDefaultSubject = true;
options.UseDefaultAction = true;
})
.AddDefaultHttpEventData(subjectOptions =>
{
subjectOptions.SubjectIdentifierClaim = ClaimsConsts.Sub;
subjectOptions.SubjectNameClaim = ClaimsConsts.Name;
},
actionOptions =>
{
actionOptions.IncludeFormVariables = true;
})
.AddDefaultStore(options => options.UseSqlServer(Configuration.GetConnectionString("ApplicationDbContext"),
optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly)))
.AddDefaultAuditSink();
Setup for machine application (e.g. background jobs):
services.AddAuditLogging(options =>
{
options.UseDefaultAction = false;
options.Source = "Web"
})
.AddStaticEventSubject(subject =>
{
subject.SubjectType = AuditSubjectTypes.Machine;
subject.SubjectIdentifier = EmailServiceConsts.Name;
subject.SubjectName = Environment.MachineName;
})
.AddDefaultEventAction()
.AddStore<ApplicationDbContext, AuditLog, AuditLoggingRepository<ApplicationDbContext, AuditLog>>(options =>
options.UseSqlServer(configuration.GetConnectionString("ApplicationDbConnection"),
optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly)))
.AddDefaultAuditSink();
Usage in code
// Create fake product
var productDto = new ProductDto
{
Id = Guid.NewGuid().ToString(),
Name = Guid.NewGuid().ToString(),
Category = Guid.NewGuid().ToString()
};
// Log this action
var productGetUserEvent = new ProductGetEvent
{
Product = productDto
};
Logging for user action
await _auditEventLogger.LogEventAsync(productGetUserEvent);
Logging for machine action
var productGetMachineEvent = new ProductGetEvent
{
Product = productDto,
SubjectType = AuditSubjectTypes.Machine,
SubjectName = Environment.MachineName,
SubjectIdentifier = Environment.MachineName,
Action = new { Method = nameof(Get), Class = nameof(AuditController) }
};
await _auditEventLogger.LogEventAsync(productGetMachineEvent, options =>
{
options.UseDefaultSubject = false;
options.UseDefaultAction = false;
});
ProductAddedEvent.cs
public class ProductAddedEvent : AuditEvent
{
public ProductDto ProductDto { get; set; }
}
AuditEvent - base event for logger
Property | Description |
---|---|
Event | Name of event |
Source | Source of logging events |
Category | Event category |
SubjectIdentifier | Identifier of caller which is responsible for the event |
SubjectName | Name of caller which is responsible for the event |
SubjectType | Subject Type (eg. User/Machine) |
SubjectAdditionalData | Additional information for subject |
Action | Information about request/action |
AuditLog - database table
Property | Description |
---|---|
Id | Database unique identifier for event |
Event | Name of event |
Source | Source of logging events |
Category | Event category |
SubjectIdentifier | Identifier of caller which is responsible for the event |
SubjectName | Name of caller which is responsible for the event |
SubjectType | Subject Type (eg. User/Machine) |
SubjectAdditionalData | Additional information for subject |
Action | Information about request/action |
Data | Data which are serialized into JSON format |
Created | Date and time for creating of the event |
Setup default IAuditSubject and IAuditAction
IAuditSubject
Default subject implementation for HTTP calls:
public class AuditHttpSubject : IAuditSubject
{
public AuditHttpSubject(IHttpContextAccessor accessor, AuditHttpSubjectOptions options)
{
SubjectIdentifier = accessor.HttpContext.User.FindFirst(options.SubjectIdentifierClaim)?.Value;
SubjectName = accessor.HttpContext.User.FindFirst(options.SubjectNameClaim)?.Value;
SubjectAdditionalData = new
{
RemoteIpAddress = accessor.HttpContext.Connection?.RemoteIpAddress?.ToString(),
LocalIpAddress = accessor.HttpContext.Connection?.LocalIpAddress?.ToString(),
Claims = accessor.HttpContext.User.Claims?.Select(x=> new { x.Type, x.Value })
};
}
public string SubjectName { get; set; }
public string SubjectType { get; set; } = AuditSubjectTypes.User;
public object SubjectAdditionalData { get; set; }
public string SubjectIdentifier { get; set; }
}
IAuditAction
Default action implementation for HTTP calls:
public class AuditHttpAction : IAuditAction
{
public AuditHttpAction(IHttpContextAccessor accessor, AuditHttpActionOptions options)
{
Action = new
{
TraceIdentifier = accessor.HttpContext.TraceIdentifier,
RequestUrl = accessor.HttpContext.Request.GetDisplayUrl(),
HttpMethod = accessor.HttpContext.Request.Method,
FormVariables = options.IncludeFormVariables ? HttpContextHelpers.GetFormVariables(accessor.HttpContext) : null
};
}
public object Action { get; set; }
}
Sinks
Database migrations
dotnet ef migrations add DbInit -c DefaultAuditLoggingDbContext -o Data/Migrations
dotnet ef database update -c DefaultAuditLoggingDbContext
Database sink via EntityFramework Core - DatabaseAuditEventLoggerSink
- By default it is used database sink via EntityFramework Core, for registration this default sink - it is required to register this method:
.AddDefaultStore(options => options.UseSqlServer(Configuration.GetConnectionString("ApplicationDbContext"),
optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly)))
.AddDefaultAuditSink()
AddDefaultStore:
This method register default implementation of:
DefaultAuditLoggingDbContext
- Default DbContext for access to databaseAuditLog
- Entity for logging all audit stuffAuditLoggingRepository
- Repository for access to database, which contains GRUD method for access toAuditLog
table.In the background it is used method called:
AddStore
- which is possible to use instead of AddDefaultStore and specify individual implementation of these objects above
builder.AddStore<DefaultAuditLoggingDbContext, AuditLog, AuditLoggingRepository<DefaultAuditLoggingDbContext, AuditLog>>(dbContextOptions);
AddDefaultAuditSink:
- This method is for registration of default Sink:
builder.AddAuditSinks<DatabaseAuditEventLoggerSink<AuditLog>>();
How to use own Sink
- It is necessary to implement interface
IAuditEventLoggerSink
and one single method called:
Task PersistAsync(AuditEvent auditEvent);
- Then you can register your new sink via method -
.AddAuditSinks<>
- which has overload for maximum 8 sinks.
Example
Source code
- Please, check out the project
Skoruba.AuditLogging.Host
- which contains example with Asp.Net Core API - with fake authentication for testing purpose only. 😊
Output in JSON format
{
"Id":1,
"Event":"ProductGetEvent",
"Category":"Web",
"SubjectIdentifier":"30256997-4096-428d-bfc7-8593d263b8eb",
"SubjectName":"bob",
"SubjectType":"User",
"SubjectAdditionalData":{
"RemoteIpAddress":"::1",
"LocalIpAddress":"::1",
"Claims":[
{
"Type":"name",
"Value":"bob"
},
{
"Type":"sub",
"Value":"30256997-4096-428d-bfc7-8593d263b8eb"
},
{
"Type":"role",
"Value":"31fad6ad-9df3-4e7f-b73f-68dc7d2636c6"
}
]
},
"Action":{
"TraceIdentifier":"80000025-0000-ff00-b63f-84710c7967bb",
"RequestUrl":"https://localhost:44319/api/audit",
"HttpMethod":"GET"
},
"Data":{
"Product":{
"Id":"7d7138b6-e5c3-4548-814c-9119ddb1f785",
"Name":"c9bc91fe-79f2-439b-8bfa-be3f71947b63",
"Category":"b3f2f9d2-67d5-4b52-8156-04232adf0c4b"
}
},
"Created":"2019-09-09T12:03:12.7729634"
}
Licence
This repository is licensed under the terms of the MIT license.
NOTE: This repository uses the source code from https://github.com/IdentityServer/IdentityServer4 which is under the terms of the Apache License 2.0.
Acknowledgements
- This library is inspired by EventService from IdentityServer4.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Iguga.AuditLogging (>= 1.1.2)
- Microsoft.EntityFrameworkCore (>= 6.0.7)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.