Audit the Current User or Host Identity (EF Core)
- 3 minutes to read
The Audit Trail Module gets information on the user who changed an object from the Security System. If your application uses custom authentication instead of the Security System, you can use the following properties to determine the user:
- IPrincipalProvider.User.Identity.Name in ASP.NET Core Blazor applications
- WindowsIdentity.Name in WinForms applications
ASP.NET Core Blazor
In the ASP.NET Core Blazor application project (MySolution.Blazor.Server), create the following new classes:
MyUserProvider
that implements theIAuditUserProvider
interfaceMyAuditDefaultStringProvider
that is anAuditDefaultStringProvider
descendant
using DevExpress.ExpressApp.Security; using DevExpress.ExpressApp.Services.Localization; using DevExpress.Persistent.BaseImpl.EFCore.AuditTrail; public class MyUserProvider : IAuditUserProvider { private readonly IPrincipalProvider principalProvider; public MyUserProvider(IPrincipalProvider principalProvider) { this.principalProvider = principalProvider; } public object GetUser() { return principalProvider.User.Identity.Name; } public object GetUserId() { return principalProvider.User.Identity.Name; } public Type GetUserType() { return typeof(string); } } public class MyAuditDefaultStringProvider : AuditDefaultStringProvider { public MyAuditDefaultStringProvider(ICaptionHelperProvider captionHelperProvider) : base(captionHelperProvider) { } public override string GetDefaultString(object targetObject, Type objectType, object objectKey) { if(targetObject.GetType().Equals(typeof(string))) { return targetObject.ToString(); } return base.GetDefaultString(targetObject, objectType, objectKey); } }
In the
Startup.ConfigureServices
method (the MySolution.Blazor.Server\Startup.cs file), do the following:- add the custom implementation of the
IPrincipalProvider
service (HttpContextPrincipalProvider
); - set the
AuditUserProviderType
andAuditDefaultStringProviderType
properties to the customMyUserProvider
andMyAuditDefaultStringProvider
types.
File: MySolution.Blazor.Server\Startup.cs
using DevExpress.Persistent.BaseImpl.EFCore.AuditTrail; public class Startup { // ... public void ConfigureServices(IServiceCollection services) { // ... services.AddScoped(typeof(IPrincipalProvider), typeof(HttpContextPrincipalProvider)); services.AddXaf(Configuration, builder => { // ... builder.ObjectSpaceProviders .AddEFCore(options => options.PreFetchReferenceProperties()) .WithAuditedDbContext(contexts => { contexts.Configure<MySolutionEFCoreDbContext, MySolutionAuditingDbContext>( (serviceProvider, businessObjectDbContextOptions) => { // ... }, (serviceProvider, auditHistoryDbContextOptions) => { // ... }, auditTrailOptions => { auditTrailOptions.AuditUserProviderType = typeof(MyUserProvider); auditTrailOptions.AuditDefaultStringProviderType = typeof(MyAuditDefaultStringProvider); }); }) // ...
- add the custom implementation of the
Note
The MyUserProvider
and MyAuditDefaultStringProvider
types are registered as scoped services. You can use the IAuditUserProvider
and IAuditDefaultStringProvider
interfaces to access them.
WinForms
In the WinForms application project (MySolution.Win), create the following new classes:
MyUserProvider
that implements theIAuditUserProvider
interfaceMyAuditDefaultStringProvider
that is anAuditDefaultStringProvider
descendant
using DevExpress.ExpressApp.Services.Localization; using DevExpress.Persistent.BaseImpl.EFCore.AuditTrail; using System.Security.Principal; public class MyUserProvider : IAuditUserProvider { public object GetUser() { return WindowsIdentity.GetCurrent().Name; } public object GetUserId() { return WindowsIdentity.GetCurrent().Name; } public Type GetUserType() { return typeof(string); } } public class MyAuditDefaultStringProvider : AuditDefaultStringProvider { public MyAuditDefaultStringProvider(ICaptionHelperProvider captionHelperProvider) : base(captionHelperProvider) { } public override string GetDefaultString(object targetObject, Type objectType, object objectKey) { if(targetObject.GetType().Equals(typeof(string))) { return targetObject.ToString(); } return base.GetDefaultString(targetObject, objectType, objectKey); } }
In the
ApplicationBuilder.BuildApplication
method (MySolution.Win\Startup.cs file), set theAuditUserProviderType
andAuditDefaultStringProviderType
properties to the customMyUserProvider
andMyAuditDefaultStringProvider
types:File: MySolution.Win\Startup.cs
using DevExpress.Persistent.BaseImpl.EFCore.AuditTrail; public class ApplicationBuilder : IDesignTimeApplicationFactory { public static WinApplication BuildApplication(string connectionString) { // ... builder.ObjectSpaceProviders .AddEFCore(options => options.PreFetchReferenceProperties()) .WithAuditedDbContext(contexts => { contexts.Configure<MySolutionEFCoreDbContext, MySolutionAuditingDbContext>( (application, businessObjectDbContextOptions) => { // ... }, (application, auditHistoryDbContextOptions) => { // ... }, auditTrailOptions => { auditTrailOptions.AuditUserProviderType = typeof(MyUserProvider); auditTrailOptions.AuditDefaultStringProviderType = typeof(MyAuditDefaultStringProvider); }); }) // ... } // ... }