Coder Social home page Coder Social logo

thepirat000 / audit.net Goto Github PK

View Code? Open in Web Editor NEW
2.2K 82.0 319.0 4.96 MB

An extensible framework to audit executing operations in .NET and .NET Core.

License: MIT License

C# 98.13% PowerShell 0.27% Batchfile 0.72% CSS 0.04% JavaScript 0.01% HTML 0.57% TSQL 0.27%
audit-log audit entity-framework wcf mvc webapi netcore audit-logs

audit.net's Issues

Collection was modified; enumeration operation may not execute.

Hi,
I encountered a issue when using AuditScope in my MVC application like below.

AuditScope.CreateAndSave("LoginSuccess", new { username = user.username });

AuditScope.CreateAndSave("LoginFailed", new { username = user.username });

I have several controller action calls the log , however it doesn't always error out. Sometime it throws exception, and some time it works well.
the exception message is as the title:

Collection was modified; enumeration operation may not execute.

the stack trace logged as follows:

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.Collections.Generic.List1.Enumerator.MoveNextRare() at Audit.Core.Configuration.InvokeScopeCustomActions(ActionType type, AuditScope auditScope) at Audit.Core.AuditScope.SaveEvent(Boolean forceInsert) at Audit.Core.AuditScope..ctor(String eventType, Func1 target, Object extraFields, AuditDataProvider dataProvider, Nullable`1 creationPolicy, Boolean isCreateAndSave)
at Audit.Core.AuditScope.CreateAndSave(String eventType, Object extraFields, AuditDataProvider dataProvider)

So my when i looked up the source code, in the class Audit.Core.Configuration , you have

internal static void InvokeScopeCustomActions(ActionType type, AuditScope auditScope)
{
            foreach (var action in AuditScopeActions[type])
            {
                action.Invoke(auditScope);
            }
}

the above function loop through the AuditScopeActions Dictionary defined as

internal static Dictionary<ActionType, List<Action<AuditScope>>> AuditScopeActions { get; private set; }

Could that be because the Dictionary isn't thread safe, so when multiple thread from my MVC web application reads and writes it concurrently, it throws the error?

let me know if i am mistaken. thank you.

lose the Authentication after mvc Update. Cause is audit.net

Hi Daniel,
the audit.net runs on my project since over two months, but I updated all packages yesterday, now I lose Authentication. I deactivated audit configuration then works well fine. I using following code in my asp.net core startup. I wanna ask you have you any idee ? Thank you very much

app.Use(async (context, next) =>
{
Audit.Core.Configuration.AddCustomAction(ActionType.OnEventSaving, scope =>
{
if (scope.Event.Environment.Exception != null)
{
scope.SetCustomField("Fehler", true);
}
if (context.User.Identity.Name != null)
{
try
{
scope.Event.Environment.UserName = context.User.Identity.Name.ToString();
scope.Event.Environment.MachineName = context.Connection.RemoteIpAddress.ToString();
}
catch (Exception)
{
scope.Event.Environment.UserName = "Fehler";
scope.Event.Environment.MachineName = "Fehler";
}
}
});
if (context.Request.IsHttps)
{
await next();
}
else
{
var withHttps = "https://" + context.Request.Host + context.Request.Path;
context.Response.Redirect(withHttps);
}
});

Default Configuration for ASP MVC

Hi,

I was looking at your help for the APS MVC 4 / 5, the picture really helped.

Is there default configuration on startup to just audit all actions/or atleast by controller, rather than putting on each action(by roles)? to profile things like number of times a password was failed/ reset etc

thanks

Problem with inherited Entities

Hi,

I'm trying to integrate the Audit.NET library with my existing code. All of my entities inherit from an abstract base class. The code is not working and an error is thrown at the step "Get the entity type from the model that maps to the CLR type" in EntityKeyHelper.cs. The code is trying to find a CLR type for my base class, which cannot work properly because it doesn't exist in objectItemCollection. I'm not sure if it is correct to get the base entity type (GetBaseEntityType) for the given entity.

Regards
Sven

Audit.WebApi: audit \Token call

We have plugged in the Audit.WebApi via a global filter. but the authentication call to \Token is not being recorded.

I assume this is because it is not a ApiController call.

any idea how i could get this to work

Audit.WebApi Never Log Responce Content

@thepirat000 Because System.Web.Http.Filters.ActionFilterAttribute.OnActionExecuted method HttpActionExecutedContext.Response.Content will be a unsekable stream when using owin, auditAction.ResponseBody will always be empty.

To fix it ,I added a Middleware to use bufferred stream to replace networkInputStream, then I can get the HttpActionExecutedContext.Response.Content and read it as string.
I posted here angularsen/AspNetHttpLogger#3.

I think you`d better add a Notice on README or somewhere, or fix it in you way, that will helpful.

Missing method exception in GetEntityName in AuditDbContext.Core.cs

entityType.SqlServer() method is not found when trying to get entity name

System.MissingMethodException: Method not found: 'Microsoft.EntityFrameworkCore.Metadata.IRelationalEntityTypeAnnotations Microsoft.EntityFrameworkCore.SqlServerMetadataExtensions.SqlServer(Microsoft.EntityFrameworkCore.Metadata.IEntityType)'. at Audit.EntityFramework.AuditDbContext.GetEntityName(IEntityType entityType) at Audit.EntityFramework.AuditDbContext.CreateAuditEvent(Boolean includeEntities, AuditOptionMode mode) at Audit.EntityFramework.AuditDbContext.SaveChanges()

Audit.WebAPI Ignores EventCreationPolicy

I've come across an issue whereby the WebAPI extension appears to be ignoring the EventCreation Policy.

I've set the policy in two ways, both in the fluent style as follows:

			Audit.Core.Configuration.CreationPolicy = EventCreationPolicy.InsertOnStartReplaceOnEnd;
			var connectionString = ConfigurationManager.ConnectionStrings[contextName].ConnectionString;
			Audit.Core.Configuration
				.Setup()
				.UseSqlServer(config => config.ConnectionString(connectionString)
						.Schema("dbo")
						.TableName("events")
						.IdColumnName("id")
						.JsonColumnName("data")
						.LastUpdatedColumnName("lastUpdatedDate")
						)
				.WithCreationPolicy(EventCreationPolicy.InsertOnStartReplaceOnEnd);

however all my events are only being written to the log at the end of the request, and none of the events have a populated 'lastUpdatedField'

Environment object on IIS is just the user running the IIS server

I'm running Audit.NET on an API deployed in IIS. The environment data for each call that gets audited is always the same and pretty much of no value, as follows:

"Environment": {
    "UserName": "DotNet Core",
    "MachineName": "HOFFELL",
    "DomainName": "IIS APPPOOL",
    "CallingMethodName": "SomeController.Get()",
    "AssemblyName": "Api, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
    "Culture": "is-IS"
},

Is it possible to pass in more useful information, and how to achieve it, related to the user that is calling the api?

Scope nesting and db schema

Hi,
I'm find your library very promising for my project, but I have couple of q's:

  1. Can this library provide nested audit scopes? How I can do that?
    I need to track all things in http request boundary and I interested in writing single event to store,
    this event should hold data entries smth like:
    (Request) -> (Application scope) -> (Business scope) -> (EF scope)
    where Request and EF holding data which already implemented in your extensions(Mvc,Sql),
    Application and Business holding custom audit data

  2. How to make custom DB schema for storing event not in json?

Thanks in advance!
P.S: You making good stuff ๐Ÿ‘

Track only crUD changes.

Is there a way I only track Update and Delete actions of my models?
And its also capture DBUpdate Exceptions, where changes were not successful. How can I exclude these as well?
"Valid":true,"ValidationResults":[]}],"Result":0,"Success":false,"ErrorMessage":"(DbUpdateException) An error occurred while updating the entries. See the inner exception for details.

Is there any way to improve performance?

I have tried Audit.Mvc with FileDataProvider and made a performance test as shown below:

Audit.Core.Configuration.Setup()
                .UseFileLogProvider(config => config
                    .DirectoryBuilder(_ => $@"C:\Logs\{DateTime.Now:yyyy-MM-dd}")
                    .FilenamePrefix("Event_"));
    [Audit]
    public IActionResult Index()

result:

Speed=34177 pages/min
    //[Audit]
    public IActionResult Index()

result:

Speed=137437 pages/min

I think that wrote audit data immediately, or into independent files will cause performance issue. Is there any way to write all audit data into one file or make a batch writing?

Exception occurred when input data has html code

Hi @thepirat000
I got an error when the request form data has html code, the Audit.Mvc.AuditAttribute class method private static IDictionary<string, string> ToDictionary(NameValueCollection col) occur an exception "System.Web.HttpRequestValidationException: 'A potentially dangerous Request.Form value was detected from the client (Html="
").'" , would you help to check this issue?
Below image for your reference.

image

CallingMethod and Assembly are one frame too high when using extensions

When using some extensions which implement attributes(currently at least Audit.Mvc and Audit.WebApi) and an action is audited, the record that is created contains something like this

        "AssemblyName": "Audit.Mvc, Version=4.10.0.0, Culture=neutral, PublicKeyToken=null",
        "CallingMethodName": "Audit.Mvc.AuditAttribute.OnActionExecuting()"

If you explicitly create the auditScope, it works as expected(meaning it references my assembly and calling method)

Guessing it's breaking because AuditScope.cs is hardcoded to 2, when, if coming from an attribute in this case, the stack would be one level deeper.

var callingMethod = new StackFrame(2).GetMethod();

This is super low priority however, I'm getting beautiful audits and they currently include the correct Controller and Action. Having the assembly and method would simply be sugar on top.

Thanks again for an awesome product.

Multiple EntityTypeMapping elements in EDMX

Hi, and let me start by saying thanks for the awesome project.

I recently integrated Audit.EntityFramework into an existing project that uses an EDMX file. It worked perfectly, except for one entity that is mapped to modification functions. After some digging, I discovered that the designer had created two EntityTypeMapping elements for the entity, one containing the MappingFragment, and the other containing the ModificationFunctionMapping. This appears to be perfectly valid inside the various EF components, but results in an InvalidOperationException ("Sequence contains more than one element.") on line 161 of EntityKeyHelper.cs.

I've managed to get around the error by merging the two EntityTypeMapping elements in the EDMX, but since the designer has a mind of it's own, I wouldn't be surprised if it puts things back to the way they were the next time the file is updated from the database.

I noticed that, at runtime, EF had merged the function mapping metadata into the EntityTypeMapping instance that contained the fragment, however the opposite was not true, so it might be possible to prevent the error by filtering out EntityTypeMapping instances that don't contain any fragments. i.e. Line 161 could be updated to:

            .EntityTypeMappings.Single(m => m.Fragments.Count != 0)

Regards
Rory

Audit.MVC CreationPolicy weirdness

Setting CreationPolicy to InsertOnEnd is behaving the same as setting it to InsertOnStartInsertOnEnd. Specifically it appears to be firing the Insert event for OnActionExecuted and OnResultExecuted. It is my understanding that InsertOnEnd should cause it to only fire the insert event when the scope is disposed, which happens in OnResultExecuted.

This is what I'm attempting to use:

Configuration.Setup()
	.UseDynamicProvider(config => config.OnInsert(auditEvent =>
		//Do something
	))
	.WithCreationPolicy(EventCreationPolicy.InsertOnEnd);

The result of this is that I'm getting nearly duplicate log entries.

Thoughts?

Responce Body + Client IP ADDRESS

Hello,

We have 4 apps which are already in production but for auditing we have to write a lot of code so we were looking for some robust mechanism with same functionality but with less code.

I am loving it to use AUDIT.NET believe me it only takes one day to attach to all apps.
Thanks.

Well i am looking for two things

  1. Is there any way to store client IP in Insert-event Method.
  2. I want to store both client request JSON and response body JSON .

Thanks

ContainerNameBuilder?

Hi and thanks for the awesome Audit package you created :)

We are creating a lot of audit logs in azure and we need to remove them when they reach a certain age.
Deleting the files one by one takes to long time. If there were a ContainerNameBuilder, I could create a new container per month, and delete this container after a certain time and all the files will be deleted with it :)

Another question: Whats the performance cost for auditing to azure blobs? Are you batching the updates? Runing the update async or on another thread?

Regards
//Per

Mark Audit.NET CLS Compliant

Would it be possible to mark the Audit.NET assembly CLS compliant by adding the ClsCompliantAttribute to the assembly.info file?

[assembly: CLSCompliant(true)]

Thanks for considering.

Audit Default Directory File Output

I'm not sure how to change the default Directory. It always save to IIS express when I run in local. Do you have example code for this?

Please assists. Thanks.

public class CustomAuditDataProvider : Audit.Core.Providers.FileDataProvider
    {
        public override object InsertEvent(AuditEvent auditEvent)
        {
            //FileDataProvider fileDataProvider = new FileDataProvider();

            DirectoryPath = "C://Users//XXXX";
            // AuditEvent provides a ToJson() method
            string json = auditEvent.ToJson();
            // Write the json representation of the event to a randomly named file
            var fileName = "Log" + Guid.NewGuid().ToString() + ".json";
            File.WriteAllText(fileName, json);
            return fileName;
        }

    }

Constructor missing in AuditIdentityDBContext

I am trying to use this in one of my MVC 4.5 application and my DB context is defined as below:

public class MyDBContext : AuditIdentityDbContext<User>
    {
        public MyDBContext()
            : base("MyDBContext", throwIfV1Schema: false)
        {
        }
          //Additional DbSets here...
     }

While compiling the application it throws error in Constructor for - base("MyDBContext", throwIfV1Schema: false). I identified that the below constructor is missing in AuditIdentityDbContext and AuditDBContext class:

 /// <summary>
        ///  Constructor which takes the connection string to use
        /// </summary>
        /// <param name="nameOrConnectionString"></param>
        /// <param name="throwIfV1Schema">Will throw an exception if the schema matches that of Identity 1.0.0</param>
        public AuditIdentityDbContext(string nameOrConnectionString, bool throwIfV1Schema)
            : base(nameOrConnectionString)
        {
            if (throwIfV1Schema)
            {
                _helper.SetConfig(this);
            }
        }  

I added this constructor in Audit.EntityFramework Source in both the classes and added a reference of that source in Project and it started working fine.

Would you suggest to add this in this package?

Please let me know in case you need any additional details.

Thanks,
Dhaval Limbad

Can this library can be used in MVC application using .Net Framework 4.0/3.5 ?

Firstly, Thanks a lot for creating this Awesome Library. I love using it.
I am new to package and have came across below issue while using this in one my application.
I added reference of Audit.net 6.2.0 in my MVC application built on .Net Framework 4.0.
In Global.asax Start_Application event when i use below configuration, it gives me System.Object error:

Audit.Core.Configuration.DataProvider = new Audit.SqlServer.Providers.SqlDataProvider()
{
ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["AuditDBConnection"].ConnectionString,
Schema = "odb",
TableName = "LOG_JSON",
IdColumnName = "LOG_JSON_ID",
JsonColumnName = "JSON_STRING",
LastUpdatedDateColumnName = "CREATED_DATE" ,

        };

Error i get while using "Audit.Core.Configuration" in first line :

The type 'System.Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

Feature: Direct support for EntityFramework

Hi Frederico,

While playing around with Audit.NET I would love to see direct integration of EntityFramework.
I mean a possibility to save EventEntry and other data (POCO objects) directly to existing DbContexts via DbSets.
Currently I'm trying to implement my own CustomDataProvider to achieve this goal. I will try to fetch all EntityFrameworkEvents and use their data for saving.

The reason for this: I need a possibility to show the end user changes made by other users on an entity. That way I need the data in plain format to show in data grids - not json.

Regards
Sven

Unable to query CustomFields in MongoDBDataProvider

Amazing library. :)

I am trying to query single audit event by ObjectId (593feb7c2d63d072b061d966) of AuditEvent(_id) to get the difference in a Old and New document.

here is my query

mongoDataProvider.QueryEvents()
             .FirstOrDefault(ev => ev.CustomFields.Any(kvp => kvp.Key = "_id" (string)kvp.Value == auditId));

Its throwing Exception "The expression tree is not supported".

Here is sample document

{ 
    "_id" : ObjectId("593feb7c2d63d072b061d966"), 
    "Environment" : {
        "UserName" : "Patel, Anand", 
        "MachineName" : "APATEL-W10LT", 
        "DomainName" : null, 
        "CallingMethodName" : null, 
        "AssemblyName" : null, 
        "Exception" : null, 
        "Culture" : "en-US"
    }, 
    "EventType" : "593aaedc8f0dd20019fbdd40", 
    "Target" : {
        "Type" : "Template", 
        "Old" : {
            "_t" : "MongoDB.Bson.BsonDocument, MongoDB.Bson", 
            "_v" : {
                "_t" : "Template", 
                "_id" : ObjectId("593aaedc8f0dd20019fbdd40"), 
                "name" : "Import Test - 12", 
                "type" : "Web", 
                "activeIndicator" : true, 
                "parentId" : "5925d50336ed6f0019b6a660", 
                "parentIndicator" : false, 
                "createdAtUtc" : ISODate("2017-06-09T14:21:16.736+0000"), 
                "updatedAtUtc" : ISODate("0001-01-01T00:00:00.000+0000")
            }
        }, 
        "New" : {
            "_t" : "MongoDB.Bson.BsonDocument, MongoDB.Bson", 
            "_v" : {
                "_t" : "Template", 
                "_id" : ObjectId("593aaedc8f0dd20019fbdd40"), 
                "name" : "Import Test - 1222", 
                "type" : "Web", 
                "activeIndicator" : true, 
                "parentId" : "5925d50336ed6f0019b6a660", 
                "parentIndicator" : false, 
                "createdAtUtc" : ISODate("2017-06-09T14:21:16.736+0000"), 
                "updatedAtUtc" : ISODate("0001-01-01T00:00:00.000+0000")
            }
        }
    }, 
    "Comments" : [
        "Template imported."
    ], 
    "StartDate" : ISODate("2017-06-13T13:41:16.193+0000"), 
    "EndDate" : ISODate("2017-06-13T13:41:16.268+0000"), 
    "Duration" : NumberInt(75)
}

Complex properties not tracked

Hello,

I'm not sure if missed anything in the docs.
I'm trying to track EF 6 entity changes.
For simple properties it works, but for complex properties (foreign key) the change is simply ignored.

Any suggestion?

Thanks,
Sandor

Audit.EntityFramework: Old and new value are always the same

Hi!

Iยดm using Audit.EntityFramework and on log output the old and new values for changed entity are always the same!

My config on statup.cs:

Audit.Core.Configuration.Setup().UseSqlServer(c => {
                c.ConnectionString(Configuration.GetConnectionString("audit.db"));
                c.Schema("dbo");
                c.TableName("Event");
                c.IdColumnName("EventId");
                c.JsonColumnName("Data");
                c.LastUpdatedColumnName("LastUpdatedDate");
                
            });

            Audit.EntityFramework.Configuration.Setup()
                .ForAnyContext(x => x.IncludeEntityObjects(true)
                                     .AuditEventType("{context}:{database}"))
                .UseOptOut();

Thankyou for the library and support!

Configuration of MVC project with EF6

Hi,
I'm testing your library for the auditing in my application that uses EF6.
I configured SQL provider in Application_Start.

With first of the AuditScope use I got this exception:
The default DbConfiguration instance was used by the Entity Framework before the 'DbConfig' type was discovered. An instance of 'DbConfig' must be set at application start before using any Entity Framework features or must be registered in the application's config file. See http://go.microsoft.com/fwlink/?LinkId=260883 for more information.

Can you explain how to use it in MVC app with EF6 in use and the same database as target ?

AuditApiAttribute NullReferenceException

Hi, the following is the response , and found that the potential Null Reference Exception.

{
"Message": "An error has occurred."
"ExceptionMessage": "Object reference not set to an instance of an object."
"ExceptionType": "System.NullReferenceException"
"StackTrace": " at Audit.WebApi.AuditApiAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext) at System.Web.Http.Filters.ActionFilterAttribute.OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at System.Web.Http.Filters.ActionFilterAttribute.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()"
}

AuditApiAttribute class
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
actionExecutedContext.Response <--- may null if the exception throw.

Following is my modified code AuditApiAttribute.

 public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        var httpContext = GetHttpContext(actionExecutedContext.Request);
        var auditAction = httpContext.Items[AuditApiActionKey] as AuditApiAction;
        var auditScope = httpContext.Items[AuditApiScopeKey] as AuditScope;
        if (auditAction != null && auditScope != null)
        {
            auditAction.Exception = actionExecutedContext.Exception.GetExceptionInfo();
            auditAction.ModelStateErrors = IncludeModelState ? GetModelStateErrors(actionExecutedContext.ActionContext.ModelState) : null;
            auditAction.ModelStateValid = IncludeModelState ? (bool?)actionExecutedContext.ActionContext.ModelState.IsValid : null;
            auditAction.ResponseBodyType = actionExecutedContext.Response == null ? "" : actionExecutedContext.Response.Content.GetType().Name;


            if (actionExecutedContext.Response != null)
            {

                auditAction.ResponseStatus = actionExecutedContext.Response.ReasonPhrase;
                auditAction.ResponseStatusCode = (int)actionExecutedContext.Response.StatusCode;
                if (IncludeResponseBody)
                {
                    var objContent = actionExecutedContext.Response.Content as ObjectContent;
                    auditAction.ResponseBody = objContent != null
                        ? new { Type = objContent.ObjectType.Name, Value = objContent.Value }
                        : (object)actionExecutedContext.Response.Content.ReadAsStringAsync().Result;
                }
            }
            else
            {
                auditAction.ResponseStatusCode =  500 ;
                auditAction.ResponseStatus = "Internal Server Error";

            }
            // Replace the Action field and save
            auditScope.SetCustomField("Action", auditAction);
            auditScope.Save();
        }
    }

object reference not set error in DbContextHelper.SetConfig

Hi,

This great library has saved us ages in getting good auditing set up, so many thanks indeed!!

We have one small problem with it. We are using a dotnet 452 mvc app and in the Startup.startup method we are configuring a SQLProvider as follows

        public Startup(IHostingEnvironment env)
        {
            //Load application config as the first step in the startup
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
            builder.AddEnvironmentVariables();
            Configuration = builder.Build();

            //Set up a storage provider for the audit infrastructure that we are using
            //See https://github.com/thepirat000/Audit.NET
            var sqlProvider = new Audit.SqlServer.Providers.SqlDataProvider();
            sqlProvider.ConnectionString = Configuration.GetConnectionString("Link.Core.Db");
            sqlProvider.Schema = "audit";
            sqlProvider.LastUpdatedDateColumnName = "LastUpdateTime";
            Audit.Core.Configuration.Setup().UseCustomProvider(sqlProvider);

        }

We then instantiate our AuditDbContext object in the ConfigureServices method as per:

    public void ConfigureServices(IServiceCollection services) {
        //Other service setup omitted for brevity
        services.AddScoped(_ => new LinkContext(Configuration.GetConnectionString("Link.Core.Db")));
   }

The first time we hit the API service we are getting the following error raised:

System.NullReferenceException was unhandled by user code
Message=Object reference not set to an instance of an object
StackTrace:
    at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
    at Audit.EntityFramework.DbContextHelper.SetConfig(IAuditDbContext context)
    at Audit.EntityFramework.AuditDbContext..ctor(String nameOrConnectionString)
    at Link.Data.LinkContext..ctor(String connString)
    at Link.Api.Startup.<ConfigureServices>b__4_2(ISeachProvider _)
    ........ Remaining stack trace omitted for brevity

It appears to work subsequent to this so wondering if we are starting up something in the wrong order?

Thanks in advance

Iain

Multiple Data Providers

Is it possible to have multiple data providers, one to capture all the Web API activities and another to capture the Entity Framework (data layer) activities, on separate tables?

SQL Server Support for Schemas

I have a database with several schemas in it. I am currently using the API audit package and I want the event table to be stored in a certain schema. How can I configure the Audit.NET to work with a specific schema? Or is this something that will need to be coded into the application.

Hiding certain for fields or action parameters

I have some sensitive information that comes across in form fields and action parameters that I would like to either remove from the log or encrypt.

I see no way of doing this without a custom policy creation.
I was hoping (for example the MVC extension) I could hook into it and remove different fields I did not want to log at all?

Is this possible?

Invalid column name 'Id'.

Hi,

Me again.... Apologies for another intrusion.

To recap we are using .net core web api with .net 45 and EF 6.1.3

I am doing an update of an entity and am getting the error below every time I post a changed entity. All unit tests work however although those are written in a traditional c# test project. Any ideas why this would happen in the .Net Core api only?

{ "message": "Invalid column name 'Id'.", "detail": " at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext) at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters) at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass65`1.<ExecuteStoreQueryReliably>b__64() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass65`1.<ExecuteStoreQueryReliably>b__63() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryReliably[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters) at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQuery[TElement](String commandText, ExecutionOptions executionOptions, Object[] parameters) at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Audit.SqlServer.Providers.SqlDataProvider.InsertEvent(AuditEvent auditEvent) at Audit.Core.AuditScope.SaveEvent(Boolean forceInsert) at Audit.Core.AuditScope.Save() at Audit.EntityFramework.DbContextHelper.SaveScope(IAuditDbContext context, AuditScope scope, EntityFrameworkEvent event) at Audit.EntityFramework.DbContextHelper.SaveChanges(IAuditDbContext context, Func`1 baseSaveChanges) at Audit.EntityFramework.AuditDbContext.SaveChanges() at Link.Data.Services.SupplierRegistrationService.Upsert(SupplierRegistration entity) in C:\\Users\\Admin\\Source\\Repos\\LINK\\LINK\\Link.Data\\Services\\SupplierRegistrationService.cs:line 74 at Link.Api.Controllers.SupplierRegistrationsController.Put(SupplierRegistration entity) in C:\\Users\\Admin\\Source\\Repos\\LINK\\LINK\\Link.Api\\Controllers\\SupplierRegistrationsController.cs:line 40 at lambda_method(Closure , Object , Object[] ) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__25.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextExceptionFilterAsync>d__24.MoveNext()" }

Multitenancy?

Hi!
Is there a way to set the connection string to the azure storage per request?

Our customers have there own azure storage accounts and we want to be able to store there own audit logs in there own azure storage. (They are using our SAAS webapi)

Regards
Per

Missing strong name

Hi,

Would it be possible to strongly sign your release version that you package in your Nuget Package. This way the nuget can also be used in projects that require all assemblies to be signed. Make sure you make a wise decision on your key because if you change it in future versions other issues come up for backwards compatibility.

Kind regards,
Bjorn

Audit.Net WebApi AND EF6

Hi I'm currently using Audit.NET for WebApi. I've im using the attribute based approach for auditing specific api calls. This works great.
However, now I want to include whatever changes that API calls have made to the underlying EF6 scope.
My question is; can I include both webapi and ef6 audit information in the same audit record?
Also, how do I ensure that all the other EF6 are not audited?
Any ideas or thoughts?

In-Memory Database

Does Audit.EntityFramework not work with in-memory database? I need it for testing. I am using EF Core with xUnit.

I have a context factory like so:

public class DatabaseContextFactory
{
    public DatabaseContext Create()
    {
        var serviceProvider = new ServiceCollection()
            .AddEntityFrameworkInMemoryDatabase()
            .BuildServiceProvider();

        var builder = new DbContextOptionsBuilder<DatabaseContext>();
        builder.UseInMemoryDatabase()
            .UseInternalServiceProvider(serviceProvider);

        return new DatabaseContext(builder.Options);
    }
}

Where my DatabaseContext inherits from AuditDbContext:

public sealed class DatabaseContext : AuditDbContext
{
    public DatabaseContext(DbContextOptions options)
        : base(options)
    {
    }
}

I get this error when running tests:

System.IndexOutOfRangeException : Index was outside the bounds of the array.
Stack Trace:
    at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
    at Audit.EntityFramework.DbContextHelper.EnsureEntitiesIncludeIgnoreAttrCache(Type type)
    at Audit.EntityFramework.DbContextHelper.IncludeEntity(IAuditDbContext context, EntityEntry entry,  AuditOptionMode mode)
    at Audit.EntityFramework.DbContextHelper.<>c__DisplayClass19_0.<GetModifiedEntries>b__0(EntityEntry x)
    at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
    at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
    at Audit.EntityFramework.DbContextHelper.GetModifiedEntries(IAuditDbContext context)
    at Audit.EntityFramework.DbContextHelper.CreateAuditEvent(IAuditDbContext context)
    at Audit.EntityFramework.DbContextHelper.SaveChanges(IAuditDbContext context, Func`1 baseSaveChanges)
    at Audit.EntityFramework.AuditDbContext.SaveChanges()

SQL Server Provider - Trigger on Event table

I tried to create a trigger on the Event table. Whenever I wanted to add an event log in the database (with the Audit.NET.SqlServer provider) I have an issue due to the way the log is inserted in the database.
I searched in the code of the provider (SqlDataProvider.cs) and found out that it use this query to insert a line in the table :
INSERT INTO {0} ([{1}]) OUTPUT CONVERT(NVARCHAR(MAX), INSERTED.[{2}]) AS [Id] VALUES (@json)
But the trigger will always fail if the statement contains an OUTPUT.

Here is the exception :

An exception of type 'System.Data.SqlClient.SqlException' occurred in EntityFramework.SqlServer.dll but was not handled in user code
Additional information: The target table 'dbo.Event' of the DML statement cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO clause.

I did work around this issue by replacing the INSERT statement by INSERT INTO {0} ([{1}]) VALUES (@json) in the SqlDataProvider.cs (I downloaded the source of the project) file and it works just fine for me.

Audit.WebApi can`t work in selfhost webapi

Audit.WebApi can`t work in selfhost webapi , because use System.Web.dll as a reference.
It will fire a ArguementNullException, because HttpContext.Current is null.
I think using owinContext as a "WebContext" environment will make it more extensional.

Audit.WebApi Never Log Responce Content

@thepirat000 Because System.Web.Http.Filters.ActionFilterAttribute.OnActionExecuted method HttpActionExecutedContext.Response.Content will be a unsekable stream when using owin, auditAction.ResponseBody will always be empty.

To fix it ,I added a Middleware to use bufferred stream to replace networkInputStream, then I can get the HttpActionExecutedContext.Response.Content and read it as string.
I posted here angularsen/AspNetHttpLogger#3.

I think you`d better add a Notice on README or somewhere, or fix it in you way, that will helpful.

Disable Audit for a Table it remains tracking for delete.

Hello,

I used this code for disable audit for some tables:

            Audit.EntityFramework.Configuration.Setup()
                            .ForContext<MyContext>(config => config
                            .IncludeEntityObjects(false)
                            .AuditEventType("{context}:{database}"))
                            .UseOptOut()
                            .IgnoreAny(x => x.Name == "LogCmdClient" || x.Name == "BlackListBatch" || x.Name ==          "BlackListSQL" || x.Name == "ReleaseFiles");

But I noticed that when I delete something generates an occurrence in my audit log.

Does not install with Newtownsoft V9

Hi,
When I tried to install Audit.MVC

Installing Audit.NET 6.0.0.
Adding package 'Audit.NET.6.0.0' to folder 'c:\testaud\packages'
Added package 'Audit.NET.6.0.0' to folder 'c:\testaud\packages'
Install failed. Rolling back...
Package 'Audit.NET.6.0.0 : Newtonsoft.Json [9.0.1, )' does not exist in project 'TestAud'
Removing package 'Audit.NET.6.0.0 : Newtonsoft.Json [9.0.1, )' from folder 'c:\testaud\packages'
Removed package 'Audit.NET.6.0.0 : Newtonsoft.Json [9.0.1, )' from folder 'c:\testaud\packages'
Install-Package : Failed to add reference to 'Audit.NET'.
At line:1 char:1
+ Install-Package Audit.MVC
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand

Not getting changes tracked?

Hey, I've been trying today to get a combination of Audit.NET SqlServer and EF tracking changes to my database. I'm getting events to fire, but I'm not able to get any changes to be tracked? Instead I seem to get an empty list in my DB.

Is there anything in particular I need to know?

I'm configured with OptOut, and AnyContext - and my DbContext is an extension of AuditContext. I get the new state of the object perfectly fine, but no information on changes that have been made.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.