默认情况下,HttpClientFactory 日志记录会编修标头值
HttpClientFactory
的默认日志记录包括输出所有请求和响应标头的 Trace
级日志。 RedactLoggedHeaders 方法允许您指定这些标头中的哪一个是敏感标头。 不会记录这些标头的值(标头名称保持不变,但值替换为 *
)。 以前,如果未使用 RedactLoggedHeaders
将任何标头指定为敏感标头,则所有标头都被视为非敏感标头,并按原样记录其所有值。 从 .NET 9 开始,除非指定,否则所有标头都被视为敏感标头,并且默认情况下会编修所有值。
旧行为
以前,如果未调用 RedactLoggedHeaders,则所有标头都按原样记录。 如果 RedactLoggedHeaders
已调用,则对指定的标头进行编修,并按原样记录其他标头。
services.AddHttpClient("default", ...); // 1
services.AddHttpClient("redacted-predicate", ...) // 2
.RedactLoggedHeaders(h => h.StartsWith("Auth") || h.StartsWith("X-"));
services.AddHttpClient("redacted-collection", ...) // 3
.RedactLoggedHeaders(new[] { "Authorization", "X-Sensitive", });
(1) 默认值 - 未编修
trce: System.Net.Http.HttpClient.default.ClientHandler[102]
Request Headers:
Authorization: NTLM blob
X-Sensitive: some, secret, values
X-Other: some, other, values
Cache-Control: no-cache
(2) 用谓词进行编修
trce: System.Net.Http.HttpClient.redacted-predicate.ClientHandler[102]
Request Headers:
Authorization: *
X-Sensitive: *
X-Other: *
Cache-Control: no-cache
(3) 用集合进行编修
trce: System.Net.Http.HttpClient.redacted-collection.ClientHandler[102]
Request Headers:
Authorization: *
X-Sensitive: *
X-Other: some, other, values
Cache-Control: no-cache
新行为
从 .NET 9 开始,如果 RedactLoggedHeaders 未调用,将对所有标头进行编修。 如果 RedactLoggedHeaders
已调用,则对指定的标头进行编修。
services.AddHttpClient("default", ...); // 1 <--- CHANGED
services.AddHttpClient("redacted-predicate", ...) // 2 <--- remains the same
.RedactLoggedHeaders(h => h.StartsWith("Auth") || h.StartsWith("X-"));
services.AddHttpClient("redacted-collection", ...) // 3 <--- remains the same
.RedactLoggedHeaders(new[] { "Authorization", "X-Sensitive", });
(1) 默认值 - 全部已编修
trce: System.Net.Http.HttpClient.default.ClientHandler[102]
Request Headers:
Authorization: *
X-Sensitive: *
X-Other: *
Cache-Control: *
引入的版本
.NET 9 RC 1
中断性变更的类型
此更改为行为更改。
更改原因
如果未将标头指定为敏感标头,则可以在日志中公开敏感信息。 此更改默认确保日志记录安全。
建议的操作
如果要记录标头,请评估哪些标头可能包含敏感信息,并使用 RedactLoggedHeaders
API 显式指定这些标头。 可以使用 ConfigureHttpClientDefaults(IServiceCollection, Action<IHttpClientBuilder>) 为每个客户端编修标头,也可以对所有客户端进行全局编修。
请考虑使用“允许列表”方法,而不是“阻止列表”方法。
如果强烈认为标头均不包含敏感信息,或者出于内部调试目的,可以通过传递返回 false
的代理来完全禁用编修。
private static readonly string[] SafeToLogHeaders = ....;
private static readonly string[] SuperSecretHeaders = ....;
// Specify for all clients.
services.ConfigureHttpClientDefaults(b =>
b.RedactLoggedHeaders(h =>
Array.IndexOf(SafeToLogHeaders, h) == -1)); // log values only for SafeToLogHeaders
// "globally" specified RedactLoggedHeaders can be overriden per-name.
// NOTE: RedactLoggedHeaders completely replaces the previously specified check.
services.AddHttpClient("override")
.RedactLoggedHeaders(SuperSecretHeaders); // log all values except SuperSecretHeaders
// -OR-
// (dangerous) Disable header value redaction for all clients.
services.ConfigureHttpClientDefaults(b => b.RedactLoggedHeaders(_ => false));