Search code examples
c#aspnetboilerplateaudit-loggingdata-masking.net-attributes

Extending AuditedAttribute to substitute or mask audited values


I am using ABP version 3.8.2. I have enabled ABP Audit Logging and it's working fine.

Is there any way to substitute or mask Audit Log value with a different value in order to hide sensitive information like Password, Credit Card details, etc.? Maybe by extending ABP's Audited attribute.

Kindly suggest.


Solution

  • Yes, you can substitute or mask audited values in order to hide sensitive information.

    1. Implement MaskableAuditSerializer:

      public class MaskableAuditSerializer : IAuditSerializer, ITransientDependency
      {
          private readonly IAuditingConfiguration _configuration;
      
          public MaskableJsonNetAuditSerializer(IAuditingConfiguration configuration)
          {
              _configuration = configuration;
          }
      
          public string Serialize(object obj)
          {
              var options = new JsonSerializerSettings
              {
                  ContractResolver = new MaskableAuditingContractResolver(_configuration.IgnoredTypes)
              };
      
              return JsonConvert.SerializeObject(obj, options);
          }
      }
      
    2. Implement MaskableAuditingContractResolver by inheriting AuditingContractResolver:

      public class MaskableAuditingContractResolver : AuditingContractResolver
      {
          public MaskableAuditingContractResolver(List<Type> ignoredTypes)
              : base(ignoredTypes)
          {
          }
      
          protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
          {
              var property = base.CreateProperty(member, memberSerialization);
      
              if (member.IsDefined(typeof(MaskedAuditedAttribute)))
              {
                  property.ValueProvider = new MaskedValueProvider();
              }
      
              return property;
          }
      }
      
    3. Implement MaskedValueProvider:

      public class MaskedValueProvider : IValueProvider
      {
          public object GetValue(object target)
          {
              return "***";
          }
      
          public void SetValue(object target, object value)
          {
              throw new NotImplementedException();
          }
      }
      
    4. Implement MaskedAuditedAttribute by inheriting AuditedAttribute:

      public class MaskedAuditedAttribute : AuditedAttribute
      {
      }
      

    Usage

    public class LoginViewModel
    {
        [MaskedAudited]
        public string Password { get; set; }
    
        // ...
    }