diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/AbpAspNetCoreComponentsServerModule.cs b/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/AbpAspNetCoreComponentsServerModule.cs index 43648c266d..2b55ba39a7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/AbpAspNetCoreComponentsServerModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/AbpAspNetCoreComponentsServerModule.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; +using Volo.Abp.AspNetCore.Auditing; using Volo.Abp.AspNetCore.Uow; using Volo.Abp.Modularity; @@ -22,6 +23,11 @@ namespace Volo.Abp.AspNetCore.Components.Server options.IgnoredUrls.AddIfNotContains("/_blazor"); }); + Configure(options => + { + options.IgnoredUrls.AddIfNotContains("/_blazor"); + }); + Configure(options => { options.EndpointConfigureActions.Add(endpointContext => diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAspNetCoreUnitOfWorkOptions.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAspNetCoreUnitOfWorkOptions.cs new file mode 100644 index 0000000000..95aefd7056 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAspNetCoreUnitOfWorkOptions.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Auditing +{ + public class AbpAspNetCoreAuditingOptions + { + /// + /// This is used to disable the , + /// app.UseAuditing(), for the specified URLs. + /// will be disabled for URLs + /// starting with an ignored URL. + /// + public List IgnoredUrls { get; } = new List(); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs index d3f261a3f7..ddcfd61aeb 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; @@ -12,29 +13,39 @@ namespace Volo.Abp.AspNetCore.Auditing public class AbpAuditingMiddleware : IMiddleware, ITransientDependency { private readonly IAuditingManager _auditingManager; - - protected AbpAuditingOptions Options { get; } + protected AbpAuditingOptions AuditingOptions { get; } + protected AbpAspNetCoreAuditingOptions AspNetCoreAuditingOptions { get; } protected ICurrentUser CurrentUser { get; } public AbpAuditingMiddleware( IAuditingManager auditingManager, ICurrentUser currentUser, - IOptions options) + IOptions auditingOptions, + IOptions aspNetCoreAuditingOptions) { _auditingManager = auditingManager; CurrentUser = currentUser; - Options = options.Value; + AuditingOptions = auditingOptions.Value; + AspNetCoreAuditingOptions = aspNetCoreAuditingOptions.Value; } public async Task InvokeAsync(HttpContext context, RequestDelegate next) { - bool hasError = false; - using (var scope = _auditingManager.BeginScope()) + if (!AuditingOptions.IsEnabled || IsIgnoredUrl(context)) + { + await next(context); + return; + } + + var hasError = false; + using (var saveHandle = _auditingManager.BeginScope()) { try { await next(context); + + Debug.Assert(_auditingManager.Current != null); if (_auditingManager.Current.Log.Exceptions.Any()) { hasError = true; @@ -49,30 +60,31 @@ namespace Volo.Abp.AspNetCore.Auditing { if (ShouldWriteAuditLog(context, hasError)) { - await scope.SaveAsync(); + await saveHandle.SaveAsync(); } } } } - private bool ShouldWriteAuditLog(HttpContext httpContext, bool hasError = false) + private bool IsIgnoredUrl(HttpContext context) { - if (!Options.IsEnabled) - { - return false; - } + return context.Request.Path.Value != null && + AspNetCoreAuditingOptions.IgnoredUrls.Any(x => context.Request.Path.Value.StartsWith(x)); + } - if (Options.AlwaysLogOnException && hasError) + private bool ShouldWriteAuditLog(HttpContext httpContext, bool hasError) + { + if (AuditingOptions.AlwaysLogOnException && hasError) { return true; } - if (!Options.IsEnabledForAnonymousUsers && !CurrentUser.IsAuthenticated) + if (!AuditingOptions.IsEnabledForAnonymousUsers && !CurrentUser.IsAuthenticated) { return false; } - if (!Options.IsEnabledForGetRequests && + if (!AuditingOptions.IsEnabledForGetRequests && string.Equals(httpContext.Request.Method, HttpMethods.Get, StringComparison.OrdinalIgnoreCase)) { return false; diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpAspNetCoreOptions.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpAspNetCoreUnitOfWorkOptions.cs similarity index 100% rename from framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpAspNetCoreOptions.cs rename to framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpAspNetCoreUnitOfWorkOptions.cs diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs index 4a38cecc1a..55993447f2 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs @@ -22,8 +22,7 @@ namespace Volo.Abp.AspNetCore.Uow public async Task InvokeAsync(HttpContext context, RequestDelegate next) { - if (context.Request.Path.Value != null && - _options.IgnoredUrls.Any(x => context.Request.Path.Value.StartsWith(x))) + if (IsIgnoredUrl(context)) { await next(context); return; @@ -35,5 +34,11 @@ namespace Volo.Abp.AspNetCore.Uow await uow.CompleteAsync(context.RequestAborted); } } + + private bool IsIgnoredUrl(HttpContext context) + { + return context.Request.Path.Value != null && + _options.IgnoredUrls.Any(x => context.Request.Path.Value.StartsWith(x)); + } } } diff --git a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs index 9142db5617..98e830b4d7 100644 --- a/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs +++ b/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs @@ -1,10 +1,13 @@ using System; using System.Diagnostics; +using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Volo.Abp.Aspects; using Volo.Abp.DependencyInjection; using Volo.Abp.DynamicProxy; +using Volo.Abp.Users; namespace Volo.Abp.Auditing { @@ -19,12 +22,65 @@ namespace Volo.Abp.Auditing public override async Task InterceptAsync(IAbpMethodInvocation invocation) { - if (!ShouldIntercept(invocation, out var auditLog, out var auditLogAction)) + using (var serviceScope = _serviceScopeFactory.CreateScope()) { - await invocation.ProceedAsync(); - return; + var auditingHelper = serviceScope.ServiceProvider.GetRequiredService(); + var auditingOptions = serviceScope.ServiceProvider.GetRequiredService>().Value; + + if (!ShouldIntercept(invocation, auditingOptions, auditingHelper)) + { + await invocation.ProceedAsync(); + return; + } + + var auditingManager = serviceScope.ServiceProvider.GetRequiredService(); + if (auditingManager.Current != null) + { + await ProceedByLoggingAsync(invocation, auditingHelper, auditingManager.Current); + } + else + { + var currentUser = serviceScope.ServiceProvider.GetRequiredService(); + await ProcessWithNewAuditingScopeAsync(invocation, auditingOptions, currentUser, auditingManager, auditingHelper); + } + } + } + + protected virtual bool ShouldIntercept(IAbpMethodInvocation invocation, + AbpAuditingOptions options, + IAuditingHelper auditingHelper) + { + if (!options.IsEnabled) + { + return false; + } + + if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.Auditing)) + { + return false; } + if (!auditingHelper.ShouldSaveAudit(invocation.Method)) + { + return false; + } + + return true; + } + + private static async Task ProceedByLoggingAsync( + IAbpMethodInvocation invocation, + IAuditingHelper auditingHelper, + IAuditLogScope auditLogScope) + { + var auditLog = auditLogScope.Log; + var auditLogAction = auditingHelper.CreateAuditLogAction( + auditLog, + invocation.TargetObject.GetType(), + invocation.Method, + invocation.Arguments + ); + var stopwatch = Stopwatch.StartNew(); try @@ -43,45 +99,65 @@ namespace Volo.Abp.Auditing auditLog.Actions.Add(auditLogAction); } } - - protected virtual bool ShouldIntercept( - IAbpMethodInvocation invocation, - out AuditLogInfo auditLog, - out AuditLogActionInfo auditLogAction) + + private async Task ProcessWithNewAuditingScopeAsync( + IAbpMethodInvocation invocation, + AbpAuditingOptions options, + ICurrentUser currentUser, + IAuditingManager auditingManager, + IAuditingHelper auditingHelper) { - auditLog = null; - auditLogAction = null; - - if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.Auditing)) + var hasError = false; + using (var saveHandle = auditingManager.BeginScope()) { - return false; - } + try + { + await ProceedByLoggingAsync(invocation, auditingHelper, auditingManager.Current); - using (var scope = _serviceScopeFactory.CreateScope()) - { - var auditingManager = scope.ServiceProvider.GetRequiredService(); - var auditLogScope = auditingManager.Current; - if (auditLogScope == null) + Debug.Assert(auditingManager.Current != null); + if (auditingManager.Current.Log.Exceptions.Any()) + { + hasError = true; + } + } + catch (Exception) { - return false; + hasError = true; + throw; } - - var auditingHelper = scope.ServiceProvider.GetRequiredService(); - if (!auditingHelper.ShouldSaveAudit(invocation.Method)) + finally { - return false; + if (ShouldWriteAuditLog(invocation, options, currentUser, hasError)) + { + await saveHandle.SaveAsync(); + } } + } + } + + private bool ShouldWriteAuditLog( + IAbpMethodInvocation invocation, + AbpAuditingOptions options, + ICurrentUser currentUser, + bool hasError) + { + if (options.AlwaysLogOnException && hasError) + { + return true; + } - auditLog = auditLogScope.Log; - auditLogAction = auditingHelper.CreateAuditLogAction( - auditLog, - invocation.TargetObject.GetType(), - invocation.Method, - invocation.Arguments - ); + if (!options.IsEnabledForAnonymousUsers && !currentUser.IsAuthenticated) + { + return false; + } - return true; + if (!options.IsEnabledForGetRequests && + invocation.Method.Name.StartsWith("Get",StringComparison.OrdinalIgnoreCase)) + { + return false; } + + return true; } } -} +} \ No newline at end of file