Skip to content

Commit d799110

Browse files
Merge pull request #35185 from dotnet/main
Merge to Live
2 parents 0e4c467 + 2d7329a commit d799110

16 files changed

+437
-146
lines changed

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

+16-14
Original file line numberDiff line numberDiff line change
@@ -207,22 +207,22 @@ The following list shows the order of precedence for logging configuration:
207207

208208
[!INCLUDE[](~/fundamentals/http-logging/includes/index-6-7.md)]
209209

210-
:::moniker range=">= aspnetcore-10.0"
210+
:::moniker range=">= aspnetcore-9.0"
211211

212212
## Redacting sensitive data
213213

214214
Http logging with redaction can be enabled by calling `AddHttpLoggingRedaction`<!-- Microsoft.Extensions.DependencyInjection.HttpLoggingServiceCollectionExtensions.AddHttpLoggingRedaction> -->:
215215

216-
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet7&highlight=9)]
216+
[!code-csharp[](~/fundamentals/http-logging/samples/9.x/Program.cs?name=snippet7&highlight=9)]
217217

218218
For more information about .NET's data redaction library, see [Data redaction in .NET](/dotnet/core/extensions/data-redaction).
219219

220220
## Logging redaction options
221221

222222
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`:
223223

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)]
224+
[!code-csharp[](~/fundamentals/http-logging/samples/9.x/MyTaxonomyClassifications.cs)]
225+
[!code-csharp[](~/fundamentals/http-logging/samples/9.x/Program.cs?name=snippet_redactionOptions&highlight=6)]
226226

227227
With the previous redaction configuration, the output is similar to the following:
228228

@@ -254,53 +254,55 @@ info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
254254
<!-- Microsoft.AspNetCore.Diagnostics.Logging.IncomingPathLoggingMode.Structured> -->
255255
* `Structured` logs the request path with parameters included.
256256

257-
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=9)]
257+
[!code-csharp[](~/fundamentals/http-logging/samples/9.x/Program.cs?name=snippet_redactionOptions&highlight=9)]
258258

259259
### RequestPathParameterRedactionMode
260260

261261
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.RequestPathParameterRedactionMode> -->
262-
`RequestPathParameterRedactionMode` specifies how route parameters in the request path should be redacted, whether `Strict` or `None`.
262+
`RequestPathParameterRedactionMode` specifies how route parameters in the request path should be redacted, whether `Strict`, `Loose`, or `None`.
263263

264264
<!-- Microsoft.AspNetCore.Diagnostics.Logging.HttpRouteParameterRedactionMode.Strict>-->
265-
* `Strict`: request route parameters are considered as sensitive and are redacted by default.
265+
* `Strict`: Request route parameters are considered sensitive, require explicit annotation with a data classification, and are redacted by default.
266+
<!-- Microsoft.AspNetCore.Diagnostics.Logging.HttpRouteParameterRedactionMode.Loose>-->
267+
* `Loose`: All parameters are considered as non-sensitive and included as-is by default.
266268
<!-- Microsoft.AspNetCore.Diagnostics.Logging.HttpRouteParameterRedactionMode.None>-->
267-
* `None`: request route parameters are considered as non-sensitive and logged as-is by default.
269+
* `None`: Route parameters aren't redacted regardless of the presence of data classification annotations.
268270

269-
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=8)]
271+
[!code-csharp[](~/fundamentals/http-logging/samples/9.x/Program.cs?name=snippet_redactionOptions&highlight=8)]
270272

271273
### RequestHeadersDataClasses
272274

273275
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.RequestHeadersDataClasses>-->
274276
`RequestHeadersDataClasses` maps request headers to their data classification, which determines how they are redacted:
275277

276-
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=10)]
278+
[!code-csharp[](~/fundamentals/http-logging/samples/9.x/Program.cs?name=snippet_redactionOptions&highlight=10)]
277279

278280
### ResponseHeadersDataClasses
279281

280282
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.ResponseHeadersDataClasses>-->
281283
`ResponseHeadersDataClasses`, similar to <!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.RequestHeadersDataClasses>--> `RequestHeadersDataClasses`, but for response headers:
282284

283-
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=11)]
285+
[!code-csharp[](~/fundamentals/http-logging/samples/9.x/Program.cs?name=snippet_redactionOptions&highlight=11)]
284286

285287
### RouteParameterDataClasses
286288

287289
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.RouteParameterDataClasses>-->
288290
`RouteParameterDataClasses` maps route parameters to their data classification:
289291

290-
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=12,13,14,15)]
292+
[!code-csharp[](~/fundamentals/http-logging/samples/9.x/Program.cs?name=snippet_redactionOptions&highlight=12,13,14,15)]
291293

292294
### ExcludePathStartsWith
293295

294296
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.ExcludePathStartsWith>-->
295297
`ExcludePathStartsWith` specifies paths that should be excluded from logging entirely:
296298

297-
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=16,17)]
299+
[!code-csharp[](~/fundamentals/http-logging/samples/9.x/Program.cs?name=snippet_redactionOptions&highlight=16,17)]
298300

299301
### IncludeUnmatchedRoutes
300302

301303
<!-- Microsoft.AspNetCore.Diagnostics.Logging.LoggingRedactionOptions.IncludeUnmatchedRoutes>-->
302304
`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:
303305

304-
[!code-csharp[](~/fundamentals/http-logging/samples/8.x/Program.cs?name=snippet_redactionOptions&highlight=18)]
306+
[!code-csharp[](~/fundamentals/http-logging/samples/9.x/Program.cs?name=snippet_redactionOptions&highlight=18)]
305307

306308
:::moniker-end

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

-6
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,4 @@
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
</PropertyGroup>
8-
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-
148
</Project>

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

+1-48
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#define THIRD // FIRST SECOND THIRD FORTH
1+
#define THIRD // FIRST SECOND THIRD
22
#if NEVER
33
#elif FIRST
44
// <snippet_Addservices>
@@ -60,54 +60,10 @@
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>
10663
#elif THIRD
10764
// <snippet3>
10865
using HttpLoggingSample;
10966
using Microsoft.AspNetCore.HttpLogging;
110-
// <snippet7>
11167
// <snippet4>
11268
var builder = WebApplication.CreateBuilder(args);
11369

@@ -117,9 +73,6 @@
11773
});
11874
builder.Services.AddHttpLoggingInterceptor<SampleHttpLoggingInterceptor>();
11975
// </snippet4>
120-
builder.Services.AddRedaction();
121-
builder.Services.AddHttpLoggingRedaction(op => { });
122-
// </snippet7>
12376
var app = builder.Build();
12477

12578
if (!app.Environment.IsDevelopment())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.Middleware" Version="9.4.0" />
11+
<PackageReference Include="Microsoft.Extensions.Compliance.Redaction" Version="9.4.0" />
12+
</ItemGroup>
13+
14+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Microsoft.Extensions.Http.Diagnostics;
2+
using Microsoft.AspNetCore.Diagnostics.Logging;
3+
using Microsoft.Extensions.Compliance.Classification;
4+
using HttpLoggingSample;
5+
using Microsoft.Net.Http.Headers;
6+
7+
// <snippet_redactionOptions>
8+
var builder = WebApplication.CreateBuilder(args);
9+
10+
builder.Services.AddHttpLogging(o => { });
11+
builder.Services.AddRedaction();
12+
13+
builder.Services.AddHttpLoggingRedaction(op =>
14+
{
15+
op.RequestPathParameterRedactionMode = HttpRouteParameterRedactionMode.None;
16+
op.RequestPathLoggingMode = IncomingPathLoggingMode.Formatted;
17+
op.RequestHeadersDataClasses.Add(HeaderNames.Accept, MyTaxonomyClassifications.Public);
18+
op.ResponseHeadersDataClasses.Add(HeaderNames.ContentType, MyTaxonomyClassifications.Private);
19+
op.RouteParameterDataClasses = new Dictionary<string, DataClassification>
20+
{
21+
{ "one", MyTaxonomyClassifications.Personal },
22+
};
23+
// Add the paths that should be filtered, with a leading '/'.
24+
op.ExcludePathStartsWith.Add("/home");
25+
op.IncludeUnmatchedRoutes = true;
26+
});
27+
28+
var app = builder.Build();
29+
30+
app.UseHttpLogging();
31+
32+
if (!app.Environment.IsDevelopment())
33+
{
34+
app.UseExceptionHandler("/Error");
35+
}
36+
app.UseStaticFiles();
37+
38+
app.MapGet("/", () => "Logged!");
39+
app.MapGet("/home", () => "Not logged!");
40+
41+
app.Run();
42+
// </snippet_redactionOptions>
43+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using Microsoft.AspNetCore.HttpLogging;
2+
3+
namespace HttpLoggingSample;
4+
5+
internal sealed class SampleHttpLoggingInterceptor : IHttpLoggingInterceptor
6+
{
7+
public ValueTask OnRequestAsync(HttpLoggingInterceptorContext logContext)
8+
{
9+
if (logContext.HttpContext.Request.Method == "POST")
10+
{
11+
// Don't log anything if the request is a POST.
12+
logContext.LoggingFields = HttpLoggingFields.None;
13+
}
14+
15+
// Don't enrich if we're not going to log any part of the request.
16+
if (!logContext.IsAnyEnabled(HttpLoggingFields.Request))
17+
{
18+
return default;
19+
}
20+
21+
if (logContext.TryDisable(HttpLoggingFields.RequestPath))
22+
{
23+
RedactPath(logContext);
24+
}
25+
26+
if (logContext.TryDisable(HttpLoggingFields.RequestHeaders))
27+
{
28+
RedactRequestHeaders(logContext);
29+
}
30+
31+
EnrichRequest(logContext);
32+
33+
return default;
34+
}
35+
36+
public ValueTask OnResponseAsync(HttpLoggingInterceptorContext logContext)
37+
{
38+
// Don't enrich if we're not going to log any part of the response
39+
if (!logContext.IsAnyEnabled(HttpLoggingFields.Response))
40+
{
41+
return default;
42+
}
43+
44+
if (logContext.TryDisable(HttpLoggingFields.ResponseHeaders))
45+
{
46+
RedactResponseHeaders(logContext);
47+
}
48+
49+
EnrichResponse(logContext);
50+
51+
return default;
52+
}
53+
54+
private void RedactPath(HttpLoggingInterceptorContext logContext)
55+
{
56+
logContext.AddParameter(nameof(logContext.HttpContext.Request.Path), "RedactedPath");
57+
}
58+
59+
private void RedactRequestHeaders(HttpLoggingInterceptorContext logContext)
60+
{
61+
foreach (var header in logContext.HttpContext.Request.Headers)
62+
{
63+
logContext.AddParameter(header.Key, "RedactedHeader");
64+
}
65+
}
66+
67+
private void EnrichRequest(HttpLoggingInterceptorContext logContext)
68+
{
69+
logContext.AddParameter("RequestEnrichment", "Stuff");
70+
}
71+
72+
private void RedactResponseHeaders(HttpLoggingInterceptorContext logContext)
73+
{
74+
foreach (var header in logContext.HttpContext.Response.Headers)
75+
{
76+
logContext.AddParameter(header.Key, "RedactedHeader");
77+
}
78+
}
79+
80+
private void EnrichResponse(HttpLoggingInterceptorContext logContext)
81+
{
82+
logContext.AddParameter("ResponseEnrichment", "Stuff");
83+
}
84+
}
85+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"DetailedErrors": true,
3+
"Logging": {
4+
"LogLevel": {
5+
"Default": "Information",
6+
"Microsoft.AspNetCore": "Warning",
7+
"Microsoft.AspNetCore.Hosting": "Information",
8+
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
9+
}
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"AllowedHosts": "*"
9+
}

0 commit comments

Comments
 (0)