Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I populate my audit log UserId field when I don't have access to HttpContext?

I have a solution with two projects, my API layer and my Data layer.

The Data layer is using Entity Framework, and does not know about ASP.NET WebApi.

The API layer is using ASP.NET WebApi.

I am planning on using Audit.NET to audit record changes.

Currently, I have installed Audit.NET, Audit.EntityFramework and Audit.WebApi in my API project.

I wish to use the Audit Filter Attribute. (config.Filters.Add(new AuditApiAttribute());)

My issue is, when I come to populate the EntityLog object, I also would like to populate the UserId field with the Id of the user currently performing an authorized action, or null if the action is anonymous.

As part of my Startup.cs, I run this function to configure Audit.NET:

private void ConfigureAudit()
        {
            Audit.Core.Configuration.Setup()
                .UseEntityFramework(x => x
                    .AuditTypeMapper(t => typeof(AuditLog))
                    .AuditEntityAction<AuditLog>((ev, entry, entity) =>
                    {
                        entity.UserId = ???;
                        // other fields...
                    })
                    .IgnoreMatchedProperties()
                );
        }

Obviously at this point I cannot use HttpContext.Current.User.Identity.GetUserId() as I'm not inside a controller, and I don't see a way of passing the UserId into the Audit event.

How can I retrieve the UserId at this point?

like image 872
JH-Sen-Ren Avatar asked Sep 19 '19 10:09

JH-Sen-Ren


1 Answers

In addition to Steve answer, I guess you should be able to add a Custom Field from a OnScopeCreated custom action, like this on your asp.net startup logic:

Audit.Core.Configuration.AddCustomAction(ActionType.OnScopeCreated, scope =>
{
    scope.SetCustomField("User", HttpContext.Current.User.Identity.GetUserId());
});

So you will have that field on the AuditEvent on your EF data provider, and should be able to retrieve like this:

Audit.Core.Configuration.Setup()
    .UseEntityFramework(_ => _
        .AuditTypeMapper(t => typeof(AuditLog))
        .AuditEntityAction<AuditLog>((ev, entry, entity) =>
        {
            var x = ev.CustomFields["User"];
            ...
        })
        .IgnoreMatchedProperties());

Note: if you are only interested in auditing entity framework DB contexts, you don't need the Audit.WebApi library. That one is for auditing the controller actions.

like image 67
thepirat000 Avatar answered Nov 08 '22 13:11

thepirat000