审计模块

除了对 HTTP 请求有审计日志记录以外,ABP vNext 还提供了实体审计信息的记录功能

1、模块配置

 类型(class)是否定义了AuditedAttribute,DisableAuditingAttribute,或派生于IAuditingEnabled,2)类型方法定义AuditedAttribute

添加Auditing的拦截器

[DependsOn(
        typeof(AbpDataModule),
        typeof(AbpJsonModule),
        typeof(AbpTimingModule),
        typeof(AbpSecurityModule),
        typeof(AbpThreadingModule),
        typeof(AbpMultiTenancyModule)
        )]
    public class AbpAuditingModule : AbpModule
    {
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.OnRegistred(AuditingInterceptorRegistrar.RegisterIfNeeded);
        }
    }

整个审计日志拦截器的大体流程如下:

  1. 首先是判定 MVC 审计日志过滤器是否进行处理。
  2. 再次根据特性,和类型进行二次验证是否应该创建审计日志信息。
  3. 根据调用信息,创建 AuditLogInfo 和 AuditLogActionInfo 审计日志信息。
  4. 调用 StopWatch 的计时方法,如果出现了异常则将异常信息添加到刚才构建的 AuditLogInfo 对象中。
  5. 无论是否出现异常,都会进入 finally 语句块,这个时候会调用 StopWatch 实例的停止方法,并统计完成执行时间

ASP.NET Core 中间件

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            if (!ShouldWriteAuditLog(context))
            {
                await next(context);
                return;
            }

            using (var scope = _auditingManager.BeginScope())
            {
                try
                {
                    await next(context);
                }
                finally
                {
                    await scope.SaveAsync();
                }
            }
        }

  

2、审计的配置信息AbpAuditingOptions

HideErrors:默认为true,auditing will not throw an exceptions and it will log it when an error occurred while saving AuditLog.

IsEnabled: 默认为true,是否启用审计日志功能

ApplicationName 审计日志的应用程序名称,默认值为 null;

IsEnabledForAnonymousUsers 是否为匿名请求记录审计日志默认值 true;

List<AuditLogContributor> 审计日志功能的协作者集合,默认添加了 AspNetCoreAuditLogContributor 实现。;

List<Type> IgnoredType 默认的忽略类型,主要在序列化时使用。

IEntityHistorySelectorList EntityHistorySelectors 实体类型选择器。

IsEnabledForGetRequests:是否为 Get 请求记录审计日志,默认值 false。

3、Info信息

1)AuditLogInfo 应用名称,用户Id,用户名,租户Id,租户名,扮演Id,扮演名,执行时间,客户端信息,AuditLogActionInfo列表,Exception列表

2)AuditLogActionInfo

3)EntityChangeInfo

4)EntityPropertyChangeInfo

4、审计类接口

IMayHaveCreator;IMustHaveCreator;IHasModificationTime;IHasCreationTime;IHasCreationTime;IHasDeletionTime

ICreationAuditedObject(IHasCreationTime,IMayHaveCreator)

IModificationAuditedObject(IHasModificationTime)

IDeletionAuditedObject(IHasDeletionTime)

IAuditedObject(ICreationAuditedObject,IModificationAuditedObject)

IFullAuditedObject(IAuditedObject,IDeletionAuditedObject)

发现是 DbContext 每次进行 SaveChanges/SaveChangesAsync 的时候,就会对实体进行审计字段自动赋值操作。

  public interface IAuditPropertySetter
    {
        void SetCreationProperties(object targetObject);

        void SetModificationProperties(object targetObject);

        void SetDeletionProperties(object targetObject);
    }

5)IAuditingManager

它们分别是负责管理审计日志信息的 IAuditingManager,负责创建审计日志信息的 IAuditingHelper,还有统计接口执行时常的 Stopwatch

  public interface IAuditingManager
    {
        [CanBeNull]
        IAuditLogScope Current { get; }

        IAuditLogSaveHandle BeginScope();
    }
 public interface IAuditLogSaveHandle : IDisposable
    {
        void Save();

        Task SaveAsync();
    }

 构造出了一个可以被释放的 IAuditLogSaveHandle 对象。ABP vNext 这样做的目的,就是可以嵌套多个 Scope,即 只在某个范围内 才将审计日志记录下来。这种特性类似于 工作单元 的用法,

审计日志的序列化处理是在 IAuditingHelper 的默认实现内部被使用,可以看到构建审计日志的方法内部,通过自定义的序列化器来将 Action 的参数进行序列化处理,方便存储。 

保存AuditLogInfo

    protected virtual async Task SaveAsync(DisposableSaveHandle saveHandle)
        {
            BeforeSave(saveHandle);

            if (ShouldSave(saveHandle.AuditLog))
            {
                await _auditingStore.SaveAsync(saveHandle.AuditLog);
            }
        }

IAuditingStore 存储  AuditLogInfo

 [Dependency(TryRegister = true)]
    public class SimpleLogAuditingStore : IAuditingStore, ISingletonDependency
    {
        public ILogger<SimpleLogAuditingStore> Logger { get; set; }

        public SimpleLogAuditingStore()
        {
            Logger = NullLogger<SimpleLogAuditingStore>.Instance;
        }

        public void Save(AuditLogInfo auditInfo)
        {
            Logger.LogInformation(auditInfo.ToString());
        }

        public Task SaveAsync(AuditLogInfo auditInfo)
        {
            Save(auditInfo);
            return Task.FromResult(0);
        }
    }

AsyncLocalAmbientDataContext是异步线程安全ConcurrentDictionary<string, AsyncLocal<object>>,它有GetData,SetData

AmbientDataContextAmbientScopeProvider<T>,则是周围上下文,你可以通过GetValue获取现在的Item,

BeginScope是创建新的Item,此Item是当前,一旦退出,又指向原来的item

原文地址:https://www.cnblogs.com/cloudsu/p/11190576.html