diff --git a/src/ApplicationInsightsRequestLogging/Extensions/ServiceCollectionExtensions.cs b/src/ApplicationInsightsRequestLogging/Extensions/ServiceCollectionExtensions.cs index 5289fe1..540d15e 100644 --- a/src/ApplicationInsightsRequestLogging/Extensions/ServiceCollectionExtensions.cs +++ b/src/ApplicationInsightsRequestLogging/Extensions/ServiceCollectionExtensions.cs @@ -42,7 +42,7 @@ private static void AddBodyLogger(IServiceCollection services) services.AddScoped(); services.AddScoped(); services.AddSingleton(); - services.AddTransient(); + services.AddScoped(); } } } diff --git a/src/ApplicationInsightsRequestLogging/Filters/SensitiveDataFilter.cs b/src/ApplicationInsightsRequestLogging/Filters/SensitiveDataFilter.cs index 9b2921c..ca6692c 100644 --- a/src/ApplicationInsightsRequestLogging/Filters/SensitiveDataFilter.cs +++ b/src/ApplicationInsightsRequestLogging/Filters/SensitiveDataFilter.cs @@ -4,6 +4,7 @@ using System.Text.Json; using System.Text.Json.Nodes; using System.Text.RegularExpressions; +using Microsoft.Extensions.Options; namespace Azureblue.ApplicationInsights.RequestLogging { @@ -14,16 +15,10 @@ public class SensitiveDataFilter : ISensitiveDataFilter private readonly HashSet _sensitiveDataPropertyKeys; private readonly IEnumerable _regexesForSensitiveValues; - - public SensitiveDataFilter(BodyLoggerOptions options) : this(options.PropertyNamesWithSensitiveData, options.SensitiveDataRegexes) - { - - } - - public SensitiveDataFilter(IEnumerable sensitiveDataPropertyKeys, IEnumerable regexesForSensitiveValues) + public SensitiveDataFilter(IOptions options) { - _sensitiveDataPropertyKeys = sensitiveDataPropertyKeys.Select(t => t.ToLowerInvariant()).ToHashSet(); - _regexesForSensitiveValues = regexesForSensitiveValues; + _sensitiveDataPropertyKeys = options.Value.PropertyNamesWithSensitiveData.Select(t => t.ToLowerInvariant()).ToHashSet(); + _regexesForSensitiveValues = options.Value.SensitiveDataRegexes; } public string RemoveSensitiveData(string textOrJson) @@ -33,7 +28,8 @@ public string RemoveSensitiveData(string textOrJson) var json = JsonNode.Parse(textOrJson); if (json == null) return string.Empty; - if (json is JsonValue jValue && TestIfContainsSensitiveData("", jValue.ToString(), _sensitiveDataPropertyKeys, _regexesForSensitiveValues)) + if (json is JsonValue jValue && + TestIfContainsSensitiveData("", jValue.ToString(), _sensitiveDataPropertyKeys, _regexesForSensitiveValues)) { return SensitiveValueMask; } diff --git a/test/ApplicationInsightsRequestLoggingTests/BodyLoggerMiddlewareTests.cs b/test/ApplicationInsightsRequestLoggingTests/BodyLoggerMiddlewareTests.cs index 9f762ff..5d38613 100644 --- a/test/ApplicationInsightsRequestLoggingTests/BodyLoggerMiddlewareTests.cs +++ b/test/ApplicationInsightsRequestLoggingTests/BodyLoggerMiddlewareTests.cs @@ -15,6 +15,7 @@ using Moq; using Microsoft.Extensions.DependencyInjection; using System.Collections.Generic; +using Microsoft.Extensions.Options; namespace ApplicationInsightsRequestLoggingTests { @@ -43,13 +44,13 @@ public async void BodyLoggerMiddleware_should_not_log_request_body_if_downstream .UseTestServer() .ConfigureServices(services => { - services.AddTransient(); - services.AddTransient(); - services.AddSingleton(telemetryWriter.Object); services.AddOptions().Configure(options => { options.EnableBodyLoggingOnExceptions = false; }); + services.AddTransient(); + services.AddTransient(); + services.AddSingleton(telemetryWriter.Object); services.AddTransient(); }) .Configure(app => @@ -87,13 +88,13 @@ public async void BodyLoggerMiddleware_should_log_request_body_if_downstream_exc .UseTestServer() .ConfigureServices(services => { - services.AddTransient(); - services.AddTransient(); - services.AddSingleton(telemetryWriter.Object); services.AddOptions().Configure(options => { options.EnableBodyLoggingOnExceptions = true; }); + services.AddTransient(); + services.AddTransient(); + services.AddSingleton(telemetryWriter.Object); services.AddTransient(); }) .Configure(app => @@ -254,11 +255,13 @@ public async void BodyLoggerMiddleware_should_redact_password() .UseTestServer() .ConfigureServices(services => { - services.AddTransient(); - services.AddTransient(provider => + services.AddOptions().Configure(options => { - return new SensitiveDataFilter(new List() { "password" }, new List()); + options.PropertyNamesWithSensitiveData = new List { "password" }; + options.SensitiveDataRegexes = new List(); }); + services.AddTransient(); + services.AddTransient(); services.AddSingleton(telemetryWriter.Object); services.AddTransient(); }) diff --git a/test/ApplicationInsightsRequestLoggingTests/SensitiveDataFilter/SensitiveDataFilterTests.cs b/test/ApplicationInsightsRequestLoggingTests/SensitiveDataFilter/SensitiveDataFilterTests.cs index 90797af..c73eb98 100644 --- a/test/ApplicationInsightsRequestLoggingTests/SensitiveDataFilter/SensitiveDataFilterTests.cs +++ b/test/ApplicationInsightsRequestLoggingTests/SensitiveDataFilter/SensitiveDataFilterTests.cs @@ -1,5 +1,6 @@ using Azureblue.ApplicationInsights.RequestLogging; using FluentAssertions; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Text.Json; @@ -13,8 +14,14 @@ public class SensitiveDataFilterTests public void Should_mask_tokens_with_sensitive_data_from_json() { // Arrange + var bodyLoggerOptions = new BodyLoggerOptions + { + PropertyNamesWithSensitiveData = new List() { "token" }, + SensitiveDataRegexes = new List() + }; + var jsonWithToken = JsonSerializer.Serialize(new { token = "some-super-secret-token" }); - var filter = new SensitiveDataFilter(sensitiveDataPropertyKeys: new HashSet { "token" }, regexesForSensitiveValues: Array.Empty()); + var filter = new SensitiveDataFilter(Options.Create(bodyLoggerOptions)); // Act var result = filter.RemoveSensitiveData(jsonWithToken); @@ -28,8 +35,14 @@ public void Should_mask_tokens_with_sensitive_data_from_json() public void Should_mask_tokens_with_sensitive_data_from_nested_object_json() { // Arrange + var bodyLoggerOptions = new BodyLoggerOptions + { + PropertyNamesWithSensitiveData = new List() { "password" }, + SensitiveDataRegexes = new List() + }; + var jsonWithToken = JsonSerializer.Serialize(new { someObject = new { password = "some-super-secret-token" } }); - var filter = new SensitiveDataFilter(sensitiveDataPropertyKeys: new HashSet { "password" }, regexesForSensitiveValues: Array.Empty()); + var filter = new SensitiveDataFilter(Options.Create(bodyLoggerOptions)); // Act var result = filter.RemoveSensitiveData(jsonWithToken); @@ -43,8 +56,14 @@ public void Should_mask_tokens_with_sensitive_data_from_nested_object_json() public void Should_mask_tokens_with_sensitive_data_even_if_its_not_equal_match_json() { // Arrange + var bodyLoggerOptions = new BodyLoggerOptions + { + PropertyNamesWithSensitiveData = new List() { "password" }, + SensitiveDataRegexes = new List() + }; + var jsonWithToken = JsonSerializer.Serialize(new { someObject = new { userPassword = "some-super-secret-token" } }); - var filter = new SensitiveDataFilter(sensitiveDataPropertyKeys: new HashSet { "password" }, regexesForSensitiveValues: Array.Empty()); + var filter = new SensitiveDataFilter(Options.Create(bodyLoggerOptions)); // Act var result = filter.RemoveSensitiveData(jsonWithToken); @@ -61,8 +80,14 @@ public void Should_mask_tokens_with_sensitive_data_even_if_its_not_equal_match_j public void Should_mask_values_based_on_regex() { // Arrange + var bodyLoggerOptions = new BodyLoggerOptions + { + PropertyNamesWithSensitiveData = new List() { "password" }, + SensitiveDataRegexes = new List { CreditCardRegex } + }; + var jsonWithToken = JsonSerializer.Serialize(new { someObject = new { randomTokenName = SampleCreditCardNumber } }); - var filter = new SensitiveDataFilter(sensitiveDataPropertyKeys: new HashSet { "password" }, regexesForSensitiveValues: new List { CreditCardRegex }); + var filter = new SensitiveDataFilter(Options.Create(bodyLoggerOptions)); // Act var result = filter.RemoveSensitiveData(jsonWithToken); @@ -76,8 +101,14 @@ public void Should_mask_values_based_on_regex() public void SensitiveDataFilter_should_remove_creditcard_number_from_plain_text_if_configured() { // Arrange + var bodyLoggerOptions = new BodyLoggerOptions + { + PropertyNamesWithSensitiveData = new List() { "token" }, + SensitiveDataRegexes = new List { CreditCardRegex } + }; + var plainTextWithToken = $"token: some-not-so-{SampleCreditCardNumber}secret-token-but-with-cc-inside"; - var filter = new SensitiveDataFilter(sensitiveDataPropertyKeys: new HashSet { "token" }, regexesForSensitiveValues: new List { CreditCardRegex }); + var filter = new SensitiveDataFilter(Options.Create(bodyLoggerOptions)); // Act var result = filter.RemoveSensitiveData(plainTextWithToken);