Browse Source

Resolved #5866: Auditing interceptor should start auditing scope if auditing middleware was not added.

pull/8113/head
Halil İbrahim Kalkan 5 years ago
parent
commit
8ad7a79eec
  1. 6
      framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/AbpAspNetCoreComponentsServerModule.cs
  2. 15
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAspNetCoreUnitOfWorkOptions.cs
  3. 42
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AbpAuditingMiddleware.cs
  4. 0
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpAspNetCoreUnitOfWorkOptions.cs
  5. 9
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs
  6. 142
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs

6
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<AbpAspNetCoreAuditingOptions>(options =>
{
options.IgnoredUrls.AddIfNotContains("/_blazor");
});
Configure<AbpEndpointRouterOptions>(options =>
{
options.EndpointConfigureActions.Add(endpointContext =>

15
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
{
/// <summary>
/// This is used to disable the <see cref="AbpAuditingMiddleware"/>,
/// app.UseAuditing(), for the specified URLs.
/// <see cref="AbpAuditingMiddleware"/> will be disabled for URLs
/// starting with an ignored URL.
/// </summary>
public List<string> IgnoredUrls { get; } = new List<string>();
}
}

42
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<AbpAuditingOptions> options)
IOptions<AbpAuditingOptions> auditingOptions,
IOptions<AbpAspNetCoreAuditingOptions> 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;

0
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpAspNetCoreOptions.cs → framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpAspNetCoreUnitOfWorkOptions.cs

9
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));
}
}
}

142
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<IAuditingHelper>();
var auditingOptions = serviceScope.ServiceProvider.GetRequiredService<IOptions<AbpAuditingOptions>>().Value;
if (!ShouldIntercept(invocation, auditingOptions, auditingHelper))
{
await invocation.ProceedAsync();
return;
}
var auditingManager = serviceScope.ServiceProvider.GetRequiredService<IAuditingManager>();
if (auditingManager.Current != null)
{
await ProceedByLoggingAsync(invocation, auditingHelper, auditingManager.Current);
}
else
{
var currentUser = serviceScope.ServiceProvider.GetRequiredService<ICurrentUser>();
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<IAuditingManager>();
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<IAuditingHelper>();
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;
}
}
}
}
Loading…
Cancel
Save