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:
MyUserProviderthat implements theIAuditUserProviderinterfaceMyAuditDefaultStringProviderthat is anAuditDefaultStringProviderdescendant
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.ConfigureServicesmethod (the MySolution.Blazor.Server\Startup.cs file), do the following:- add the custom implementation of the
IPrincipalProviderservice (HttpContextPrincipalProvider); - set the
AuditUserProviderTypeandAuditDefaultStringProviderTypeproperties to the customMyUserProviderandMyAuditDefaultStringProvidertypes.
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:
MyUserProviderthat implements theIAuditUserProviderinterfaceMyAuditDefaultStringProviderthat is anAuditDefaultStringProviderdescendant
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.BuildApplicationmethod (MySolution.Win\Startup.cs file), set theAuditUserProviderTypeandAuditDefaultStringProviderTypeproperties to the customMyUserProviderandMyAuditDefaultStringProvidertypes: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); }); }) // ... } // ... }