Code Monkey home page Code Monkey logo

auditlogging's Introduction

Logo

๐Ÿ•Š๏ธ Skoruba.AuditLogging

Simple audit logging for .NET Core with EntityFramework Core support

This project is ported to .NET Core 3.1. ๐Ÿš€

How to install

dotnet add package Skoruba.AuditLogging.EntityFramework --version 1.0.0

How to use it

Setup for web application and auditing of users:

services.AddAuditLogging(options =>
                {
                    options.UseDefaultSubject = true;
                    options.UseDefaultAction = true;
                })
                .AddDefaultHttpEventData(subjectOptions =>
                    {
                        subjectOptions.SubjectIdentifierClaim = ClaimsConsts.Sub;
                        subjectOptions.SubjectNameClaim = ClaimsConsts.Name;
                    },
                    actionOptions =>
                    {
                        actionOptions.IncludeFormVariables = true;
                    })
                .AddDefaultStore(options => options.UseSqlServer(Configuration.GetConnectionString("ApplicationDbContext"),
                    optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly)))
                .AddDefaultAuditSink();

Setup for machine application (e.g. background jobs):

services.AddAuditLogging(options =>
                {
                    options.UseDefaultAction = false;
                    options.Source = "Web"
                })
                .AddStaticEventSubject(subject =>
                {
                    subject.SubjectType = AuditSubjectTypes.Machine;
                    subject.SubjectIdentifier = EmailServiceConsts.Name;
                    subject.SubjectName = Environment.MachineName;
                })
                .AddDefaultEventAction()
                .AddStore<ApplicationDbContext, AuditLog, AuditLoggingRepository<ApplicationDbContext, AuditLog>>(options =>
                    options.UseSqlServer(configuration.GetConnectionString("ApplicationDbConnection"),
                        optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly)))
                .AddDefaultAuditSink();

Usage in code

            // Create fake product
            var productDto = new ProductDto
            {
                Id = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Category = Guid.NewGuid().ToString()
            };

            // Log this action
            var productGetUserEvent = new ProductGetEvent
            {
                Product = productDto
            };           

Logging for user action

 await _auditEventLogger.LogEventAsync(productGetUserEvent);

Logging for machine action

var productGetMachineEvent = new ProductGetEvent
            {
                Product = productDto,
                SubjectType = AuditSubjectTypes.Machine,
                SubjectName = Environment.MachineName,
                SubjectIdentifier = Environment.MachineName,
                Action = new { Method = nameof(Get), Class = nameof(AuditController) }
            };

            await _auditEventLogger.LogEventAsync(productGetMachineEvent, options =>
                {
                    options.UseDefaultSubject = false;
                    options.UseDefaultAction = false;
                });

ProductAddedEvent.cs

public class ProductAddedEvent : AuditEvent
    {
        public ProductDto ProductDto { get; set; }  
    }

AuditEvent - base event for logger

Property Description
Event Name of event
Source Source of logging events
Category Event category
SubjectIdentifier Identifier of caller which is responsible for the event
SubjectName Name of caller which is responsible for the event
SubjectType Subject Type (eg. User/Machine)
SubjectAdditionalData Additional information for subject
Action Information about request/action

AuditLog - database table

Property Description
Id Database unique identifier for event
Event Name of event
Source Source of logging events
Category Event category
SubjectIdentifier Identifier of caller which is responsible for the event
SubjectName Name of caller which is responsible for the event
SubjectType Subject Type (eg. User/Machine)
SubjectAdditionalData Additional information for subject
Action Information about request/action
Data Data which are serialized into JSON format
Created Date and time for creating of the event

Setup default IAuditSubject and IAuditAction

IAuditSubject

Default subject implementation for HTTP calls:

public class AuditHttpSubject : IAuditSubject
    {
        public AuditHttpSubject(IHttpContextAccessor accessor, AuditHttpSubjectOptions options)
        {
            SubjectIdentifier = accessor.HttpContext.User.FindFirst(options.SubjectIdentifierClaim)?.Value;
            SubjectName = accessor.HttpContext.User.FindFirst(options.SubjectNameClaim)?.Value;
            SubjectAdditionalData = new
            {
                RemoteIpAddress = accessor.HttpContext.Connection?.RemoteIpAddress?.ToString(),
                LocalIpAddress = accessor.HttpContext.Connection?.LocalIpAddress?.ToString(),
                Claims = accessor.HttpContext.User.Claims?.Select(x=> new { x.Type, x.Value })
            };
        }

        public string SubjectName { get; set; }

        public string SubjectType { get; set; } = AuditSubjectTypes.User;

        public object SubjectAdditionalData { get; set; }

        public string SubjectIdentifier { get; set; }
    }

IAuditAction

Default action implementation for HTTP calls:

public class AuditHttpAction : IAuditAction
    {
        public AuditHttpAction(IHttpContextAccessor accessor, AuditHttpActionOptions options)
        {
            Action = new
            {
                TraceIdentifier = accessor.HttpContext.TraceIdentifier,
                RequestUrl = accessor.HttpContext.Request.GetDisplayUrl(),
                HttpMethod = accessor.HttpContext.Request.Method,
                FormVariables = options.IncludeFormVariables ? HttpContextHelpers.GetFormVariables(accessor.HttpContext) : null
            };
        }

        public object Action { get; set; }
    }

Sinks

Database migrations

dotnet ef migrations add DbInit -c DefaultAuditLoggingDbContext -o Data/Migrations
dotnet ef database update -c DefaultAuditLoggingDbContext

Database sink via EntityFramework Core - DatabaseAuditEventLoggerSink

  • By default it is used database sink via EntityFramework Core, for registration this default sink - it is required to register this method:
.AddDefaultStore(options => options.UseSqlServer(Configuration.GetConnectionString("ApplicationDbContext"),
                    optionsSql => optionsSql.MigrationsAssembly(migrationsAssembly)))
                .AddDefaultAuditSink()

AddDefaultStore:

  • This method register default implementation of:

  • DefaultAuditLoggingDbContext - Default DbContext for access to database

  • AuditLog - Entity for logging all audit stuff

  • AuditLoggingRepository - Repository for access to database, which contains GRUD method for access to AuditLog table.

  • In the background it is used method called: AddStore - which is possible to use instead of AddDefaultStore and specify individual implementation of these objects above

builder.AddStore<DefaultAuditLoggingDbContext, AuditLog, AuditLoggingRepository<DefaultAuditLoggingDbContext, AuditLog>>(dbContextOptions);

AddDefaultAuditSink:

  • This method is for registration of default Sink:
builder.AddAuditSinks<DatabaseAuditEventLoggerSink<AuditLog>>();

How to use own Sink

  • It is necessary to implement interface IAuditEventLoggerSink and one single method called:
Task PersistAsync(AuditEvent auditEvent);
  • Then you can register your new sink via method - .AddAuditSinks<> - which has overload for maximum 8 sinks.

Example

Source code

  • Please, check out the project Skoruba.AuditLogging.Host - which contains example with Asp.Net Core API - with fake authentication for testing purpose only. ๐Ÿ˜Š

Output in JSON format

{
      "Id":1,
      "Event":"ProductGetEvent",
      "Category":"Web",
      "SubjectIdentifier":"30256997-4096-428d-bfc7-8593d263b8eb",
      "SubjectName":"bob",
      "SubjectType":"User",
      "SubjectAdditionalData":{
         "RemoteIpAddress":"::1",
         "LocalIpAddress":"::1",
         "Claims":[
            {
               "Type":"name",
               "Value":"bob"
            },
            {
               "Type":"sub",
               "Value":"30256997-4096-428d-bfc7-8593d263b8eb"
            },
            {
               "Type":"role",
               "Value":"31fad6ad-9df3-4e7f-b73f-68dc7d2636c6"
            }
         ]
      },
      "Action":{
         "TraceIdentifier":"80000025-0000-ff00-b63f-84710c7967bb",
         "RequestUrl":"https://localhost:44319/api/audit",
         "HttpMethod":"GET"
      },
      "Data":{
         "Product":{
            "Id":"7d7138b6-e5c3-4548-814c-9119ddb1f785",
            "Name":"c9bc91fe-79f2-439b-8bfa-be3f71947b63",
            "Category":"b3f2f9d2-67d5-4b52-8156-04232adf0c4b"
         }
      },
      "Created":"2019-09-09T12:03:12.7729634"
   }

Licence

This repository is licensed under the terms of the MIT license.

NOTE: This repository uses the source code from https://github.com/IdentityServer/IdentityServer4 which is under the terms of the Apache License 2.0.

Acknowledgements

auditlogging's People

Contributors

skoruba avatar maldworth avatar

Watchers

James Cloos avatar

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.