Skip to content

Commit b4d98af

Browse files
Rick-AndersonmariamgergesR9 Fundamentals
authored
R a/mariam/redaction (#35182)
* Include redaction * sample updates * docs updates * fix * fix * fix * Add redaction to HTTP logging /4 * comment out xrefs * comment out xrefs * comment out xrefs * comment out xrefs --------- Co-authored-by: mariamgerges <[email protected]> Co-authored-by: R9 Fundamentals <[email protected]>
1 parent 805cb1a commit b4d98af

File tree

4 files changed

+167
-4
lines changed

4 files changed

+167
-4
lines changed

Diff for: aspnetcore/fundamentals/http-logging/index.md

+99
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ HTTP logging ***can reduce the performance of an app***, especially when logging
3333

3434
> [!WARNING]
3535
> HTTP logging can potentially log personally identifiable information (PII). Consider the risk and avoid logging sensitive information.
36+
> For more information about redaction, check [redacting sensitive data](#redacting-sensitive-data)
3637
3738
## Enable HTTP logging
3839

@@ -205,3 +206,101 @@ The following list shows the order of precedence for logging configuration:
205206
:::moniker-end
206207

207208
[!INCLUDE[](~/fundamentals/http-logging/includes/index-6-7.md)]
209+
210+
:::moniker range=">= aspnetcore-10.0"
211+
212+
## Redacting sensitive data
213+
214+
Http logging with redaction can be enabled by calling `AddHttpLoggingRedaction`<!-- Microsoft.Extensions.DependencyInjection.HttpLoggingServiceCollectionExtensions.AddHttpLoggingRedaction> -->:
215+
216+
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet7&highlight=9)]
217+
218+
For more information about .NET's data redaction library, see [Data redaction in .NET](/dotnet/core/extensions/data-redaction).
219+
220+
## Logging redaction options
221+
222+
To configure options for logging with redaction, call `AddHttpLoggingRedaction`<!-- Microsoft.Extensions.DependencyInjection.HttpLoggingServiceCollectionExtensions.AddHttpLoggingRedaction>--> in `Program.cs`, using the lambda to configure <!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions>--> `LoggingRedactionOptions`:
223+
224+
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/MyTaxonomyClassifications.cs)]
225+
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=6)]
226+
227+
With the previous redaction configuration, the output is similar to the following:
228+
229+
```output
230+
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[9]
231+
Request and Response:
232+
server.address: localhost:61361
233+
Path: /
234+
http.request.header.accept:
235+
Protocol: HTTP/2
236+
Method: GET
237+
Scheme: https
238+
http.response.header.content-type:
239+
StatusCode: 200
240+
Duration: 8.4684
241+
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
242+
Request finished HTTP/2 GET https://localhost:61361/ - 200 - text/plain;+charset=utf-8 105.5334ms
243+
```
244+
245+
***Note:*** Request path `/home` isn't logged because it is included in `ExcludePathStartsWith` property. `http.request.header.accept` and `http.response.header.content-type` were redacted by <!-- Microsoft.Extensions.Compliance.Redaction.ErasingRedactor> --> `Redaction.ErasingRedactor`.
246+
247+
### RequestPathLoggingMode
248+
249+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.RequestPathLoggingMode>-->
250+
`RequestPathLoggingMode` determines how the request path is logged, whether `Formatted` or `Structured`.
251+
252+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.IncomingPathLoggingMode.Formatted> -->
253+
* `Formatted` logs the request path without parameters.
254+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.IncomingPathLoggingMode.Structured> -->
255+
* `Structured` logs the request path with parameters included.
256+
257+
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=9)]
258+
259+
### RequestPathParameterRedactionMode
260+
261+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.RequestPathParameterRedactionMode> -->
262+
`RequestPathParameterRedactionMode` specifies how route parameters in the request path should be redacted, whether `Strict` or `None`.
263+
264+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.HttpRouteParameterRedactionMode.Strict>-->
265+
* `Strict`: request route parameters are considered as sensitive and are redacted by default.
266+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.HttpRouteParameterRedactionMode.None>-->
267+
* `None`: request route parameters are considered as non-sensitive and logged as-is by default.
268+
269+
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=8)]
270+
271+
### RequestHeadersDataClasses
272+
273+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.RequestHeadersDataClasses>-->
274+
`RequestHeadersDataClasses` maps request headers to their data classification, which determines how they are redacted:
275+
276+
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=10)]
277+
278+
### ResponseHeadersDataClasses
279+
280+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.ResponseHeadersDataClasses>-->
281+
`ResponseHeadersDataClasses`, similar to <!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.RequestHeadersDataClasses>--> `RequestHeadersDataClasses`, but for response headers:
282+
283+
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=11)]
284+
285+
### RouteParameterDataClasses
286+
287+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.RouteParameterDataClasses>-->
288+
`RouteParameterDataClasses` maps route parameters to their data classification:
289+
290+
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=12,13,14,15)]
291+
292+
### ExcludePathStartsWith
293+
294+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.ExcludePathStartsWith>-->
295+
`ExcludePathStartsWith` specifies paths that should be excluded from logging entirely:
296+
297+
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=16,17)]
298+
299+
### IncludeUnmatchedRoutes
300+
301+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.IncludeUnmatchedRoutes>-->
302+
`IncludeUnmatchedRoutes` allows reporting unmatched routes. If set to `true`, logs whole path of routes not identified by [Routing](xref:fundamentals/routing) instead of logging `Unknown` value for path attribute:
303+
304+
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=18)]
305+
306+
:::moniker-end

Diff for: aspnetcore/fundamentals/http-logging/samples/8.x/HttpLoggingSample.csproj

+5
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,9 @@
66
<ImplicitUsings>enable</ImplicitUsings>
77
</PropertyGroup>
88

9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.Middleware" Version="9.3.0" />
11+
<PackageReference Include="Microsoft.Extensions.Compliance.Redaction" Version="9.3.0" />
12+
</ItemGroup>
13+
914
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Microsoft.Extensions.Compliance.Classification;
2+
3+
namespace HttpLoggingSample
4+
{
5+
public static class MyTaxonomyClassifications
6+
{
7+
public static string Name => "MyTaxonomy";
8+
9+
public static DataClassification Private => new(Name, nameof(Private));
10+
public static DataClassification Public => new(Name, nameof(Public));
11+
public static DataClassification Personal => new(Name, nameof(Personal));
12+
}
13+
}

Diff for: aspnetcore/fundamentals/http-logging/samples/8.x/Program.cs

+50-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#define THIRD // FIRST SECOND THIRD
1+
#define THIRD // FIRST SECOND THIRD FORTH
22
#if NEVER
33
#elif FIRST
44
// <snippet_Addservices>
@@ -26,7 +26,7 @@
2626

2727
app.UseStaticFiles();
2828

29-
app.UseHttpLogging();
29+
app.UseHttpLogging();
3030

3131
app.Use(async (context, next) =>
3232
{
@@ -60,11 +60,54 @@
6060

6161
app.Run();
6262
// </snippet2>
63+
#elif FORTH
64+
using Microsoft.Extensions.Http.Diagnostics;
65+
using Microsoft.AspNetCore.Diagnostics.Logging;
66+
using Microsoft.Extensions.Compliance.Classification;
67+
using HttpLoggingSample;
68+
using Microsoft.Net.Http.Headers;
69+
70+
// <snippet_redactionOptions>
71+
var builder = WebApplication.CreateBuilder(args);
72+
73+
builder.Services.AddHttpLogging(o => { });
74+
builder.Services.AddRedaction();
75+
76+
builder.Services.AddHttpLoggingRedaction(op =>
77+
{
78+
op.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
79+
op.RequestPathLoggingMode = IncomingPathLoggingMode.Formatted;
80+
op.RequestHeadersDataClasses.Add(HeaderNames.Accept, MyTaxonomyClassifications.Public);
81+
op.ResponseHeadersDataClasses.Add(HeaderNames.ContentType, MyTaxonomyClassifications.Private);
82+
op.RouteParameterDataClasses = new Dictionary<string, DataClassification>
83+
{
84+
{ "one", MyTaxonomyClassifications.Personal },
85+
};
86+
// Add the paths that should be filtered, with a leading '/'.
87+
op.ExcludePathStartsWith.Add("/home");
88+
op.IncludeUnmatchedRoutes = true;
89+
});
90+
91+
var app = builder.Build();
92+
93+
app.UseHttpLogging();
94+
95+
if (!app.Environment.IsDevelopment())
96+
{
97+
app.UseExceptionHandler("/Error");
98+
}
99+
app.UseStaticFiles();
100+
101+
app.MapGet("/", () => "Logged!");
102+
app.MapGet("/home", () => "Not logged!");
103+
104+
app.Run();
105+
// </snippet_redactionOptions>
63106
#elif THIRD
64107
// <snippet3>
65108
using HttpLoggingSample;
66109
using Microsoft.AspNetCore.HttpLogging;
67-
110+
// <snippet7>
68111
// <snippet4>
69112
var builder = WebApplication.CreateBuilder(args);
70113

@@ -74,6 +117,9 @@
74117
});
75118
builder.Services.AddHttpLoggingInterceptor<SampleHttpLoggingInterceptor>();
76119
// </snippet4>
120+
builder.Services.AddRedaction();
121+
builder.Services.AddHttpLoggingRedaction(op => { });
122+
// </snippet7>
77123
var app = builder.Build();
78124

79125
if (!app.Environment.IsDevelopment())
@@ -83,7 +129,7 @@
83129

84130
app.UseStaticFiles();
85131

86-
app.UseHttpLogging();
132+
app.UseHttpLogging();
87133

88134
app.Use(async (context, next) =>
89135
{

0 commit comments

Comments
 (0)