Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/en/framework/infrastructure/audit-logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,22 @@ public class HomeController : AbpController
}
````

### Hiding Parameter Values

An audited action writes its parameter values into the audit log. Use `[DisableAuditing]` on a parameter when its value is sensitive:

````csharp
public class HomeController : AbpController
{
public async Task<ActionResult> SetConnectionString([DisableAuditing] string connectionString)
{
//...
}
}
````

The action is still audit logged and the parameter name is still written, but its value is replaced with `null`.

### Enable/Disable for Application Services & Methods

[Application service](../architecture/domain-driven-design/application-services.md) method calls also included into the audit log by default. You can use the `[DisableAuditing]` in service or method level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Volo.Abp.Auditing;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property)]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter)]
public class DisableAuditingAttribute : Attribute
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public virtual AuditLogActionInfo CreateAuditLogAction(
? type.FullName!
: "",
MethodName = method.Name,
Parameters = SerializeConvertArguments(arguments),
Parameters = SerializeConvertArguments(method, arguments),
ExecutionTime = Clock.Now
};

Expand Down Expand Up @@ -220,6 +220,24 @@ protected virtual void ExecutePreContributors(AuditLogInfo auditLogInfo)
}
}

protected virtual string SerializeConvertArguments(MethodInfo method, IDictionary<string, object?> arguments)
{
var disabledParameters = method.GetParameters()
.Where(x => x.IsDefined(typeof(DisableAuditingAttribute), true))
.Select(x => x.Name)
.ToArray();

if (disabledParameters.Any())
{
arguments = arguments.ToDictionary(
x => x.Key,
x => disabledParameters.Contains(x.Key) ? null : x.Value
);
}

return SerializeConvertArguments(arguments);
}

protected virtual string SerializeConvertArguments(IDictionary<string, object?> arguments)
{
try
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using NSubstitute;
using Shouldly;
using Volo.Abp.DependencyInjection;
using Xunit;

Expand Down Expand Up @@ -125,6 +127,20 @@ public void Should_Return_False_With_Nested_DisableAuditing()
}
}

[Fact]
public async Task Should_Not_Write_Parameter_Value_With_DisableAuditing()
{
var myAuditedObject = GetRequiredService<MyAuditedObject>();

await myAuditedObject.DoItWithSecretAsync("MyTenant", "Server=localhost;Password=1q2w3E*");

var auditLog = (AuditLogInfo)AuditingStore.ReceivedCalls().Last().GetArguments()[0]!;
var action = auditLog.Actions.Single(x => x.MethodName == nameof(MyAuditedObject.DoItWithSecretAsync));

action.Parameters.ShouldContain("MyTenant");
action.Parameters.ShouldNotContain("1q2w3E*");
}

public interface IMyAuditedObject : ITransientDependency, IAuditingEnabled
{
}
Expand All @@ -135,5 +151,10 @@ public virtual Task DoItAsync()
{
return Task.CompletedTask;
}

public virtual Task DoItWithSecretAsync(string name, [DisableAuditing] string connectionString)
{
return Task.CompletedTask;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Auditing;

namespace Volo.Abp.TenantManagement;

public interface ITenantAppService : ICrudAppService<TenantDto, Guid, GetTenantsInput, TenantCreateDto, TenantUpdateDto>
{
Task<string> GetDefaultConnectionStringAsync(Guid id);

Task UpdateDefaultConnectionStringAsync(Guid id, string defaultConnectionString);
Task UpdateDefaultConnectionStringAsync(Guid id, [DisableAuditing] string defaultConnectionString);

Task DeleteDefaultConnectionStringAsync(Guid id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local;
Expand Down Expand Up @@ -133,7 +134,7 @@ public virtual async Task<string> GetDefaultConnectionStringAsync(Guid id)
}

[Authorize(TenantManagementPermissions.Tenants.ManageConnectionStrings)]
public virtual async Task UpdateDefaultConnectionStringAsync(Guid id, string defaultConnectionString)
public virtual async Task UpdateDefaultConnectionStringAsync(Guid id, [DisableAuditing] string defaultConnectionString)
{
var tenant = await TenantRepository.GetAsync(id);
if (tenant.FindDefaultConnectionString() != defaultConnectionString)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using JetBrains.Annotations;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;

namespace Volo.Abp.TenantManagement;
Expand All @@ -10,6 +11,7 @@ public class TenantConnectionString : Entity

public virtual string Name { get; protected set; }

[DisableAuditing]
public virtual string Value { get; protected set; }

protected TenantConnectionString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Auditing;

namespace Volo.Abp.TenantManagement;

Expand Down Expand Up @@ -62,7 +63,7 @@ public virtual Task<string> GetDefaultConnectionStringAsync(Guid id)

[HttpPut]
[Route("{id}/default-connection-string")]
public virtual Task UpdateDefaultConnectionStringAsync(Guid id, string defaultConnectionString)
public virtual Task UpdateDefaultConnectionStringAsync(Guid id, [DisableAuditing] string defaultConnectionString)
{
return TenantAppService.UpdateDefaultConnectionStringAsync(id, defaultConnectionString);
}
Expand Down
Loading