Skip to main content
All docs
V24.1

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:

ASP.NET Core Blazor

  1. In the ASP.NET Core Blazor application project (MySolution.Blazor.Server), create the following new classes:

    • MyUserProvider that implements the IAuditUserProvider interface
    • MyAuditDefaultStringProvider that is an AuditDefaultStringProvider 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);
        }
    }
    
  2. 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 and AuditDefaultStringProviderType properties to the custom MyUserProvider and MyAuditDefaultStringProvider 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);
                                });
                        })
                    // ...
    

Note

The MyUserProvider and MyAuditDefaultStringProvider types are registered as scoped services. You can use the IAuditUserProvider and IAuditDefaultStringProvider interfaces to access them.

WinForms

  1. In the WinForms application project (MySolution.Win), create the following new classes:

    • MyUserProvider that implements the IAuditUserProvider interface
    • MyAuditDefaultStringProvider that is an AuditDefaultStringProvider 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);
        }
    }
    
  2. In the ApplicationBuilder.BuildApplication method (MySolution.Win\Startup.cs file), set the AuditUserProviderType and AuditDefaultStringProviderType properties to the custom MyUserProvider and MyAuditDefaultStringProvider 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);
                            });
                    })
                    // ...
        }
        // ...
    }