Browse Source
Merge pull request #26048 from abpframework/maliming/tenant-connection-string-audit
Keep tenant connection string out of the audit logs
pull/26063/head
Engincan VESKE
3 days ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with
65 additions and
5 deletions
docs/en/framework/infrastructure/audit-logging.md
framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/DisableAuditingAttribute.cs
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs
framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/AuditingHelper_Tests.cs
modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/ITenantAppService.cs
modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs
modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConnectionString.cs
modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs
@ -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.
@ -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>
@ -178,7 +178,7 @@ public class AuditingHelper : IAuditingHelper, ITransientDependency
? type . FullName !
: "" ,
MethodName = method . Name ,
Parameters = SerializeConvertArguments ( arguments ) ,
Parameters = SerializeConvertArguments ( method , arguments ) ,
ExecutionTime = Clock . Now
} ;
@ -220,6 +220,24 @@ public class AuditingHelper : IAuditingHelper, ITransientDependency
}
}
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
@ -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 ;
@ -125,6 +127,20 @@ public class AuditingHelper_Tests : AbpAuditingTestBase
}
}
[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
{
}
@ -135,5 +151,10 @@ public class AuditingHelper_Tests : AbpAuditingTestBase
{
return Task . CompletedTask ;
}
public virtual Task DoItWithSecretAsync ( string name , [ DisableAuditing ] string connectionString )
{
return Task . CompletedTask ;
}
}
}
@ -1,6 +1,7 @@
using System ;
using System.Threading.Tasks ;
using Volo.Abp.Application.Services ;
using Volo.Abp.Auditing ;
namespace Volo.Abp.TenantManagement ;
@ -8,7 +9,7 @@ public interface ITenantAppService : ICrudAppService<TenantDto, Guid, GetTenants
{
Task < string > GetDefaultConnectionStringAsync ( Guid id ) ;
Task UpdateDefaultConnectionStringAsync ( Guid id , string defaultConnectionString ) ;
Task UpdateDefaultConnectionStringAsync ( Guid id , [ DisableAuditing ] string defaultConnectionString ) ;
Task DeleteDefaultConnectionStringAsync ( Guid id ) ;
}
@ -3,6 +3,7 @@ using System.Collections.Generic;
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 ;
@ -133,7 +134,7 @@ public class TenantAppService : TenantManagementAppServiceBase, ITenantAppServic
}
[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 )
@ -1,5 +1,6 @@
using System ;
using JetBrains.Annotations ;
using Volo.Abp.Auditing ;
using Volo.Abp.Domain.Entities ;
namespace Volo.Abp.TenantManagement ;
@ -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 ( )
@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc ;
using Volo.Abp.Application.Dtos ;
using Volo.Abp.AspNetCore.Mvc ;
using Volo.Abp.Auditing ;
namespace Volo.Abp.TenantManagement ;
@ -62,7 +63,7 @@ public class TenantController : AbpControllerBase, ITenantAppService //TODO: Thr
[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 ) ;
}