.NET Core 6中UseHttpLogging如何屏蔽密码等敏感数据?
.NET Core 6中HttpLogging屏蔽敏感数据的最佳实践
一、针对特定端点屏蔽请求/响应体
如果只需要对某些高风险接口(比如登录、令牌生成接口)完全不记录请求或响应体,直接用HttpLoggingOptions的AddFilter方法就能实现,它可以根据请求上下文动态调整要记录的日志字段:
builder.Services.AddHttpLogging(options => { // 先开启所有日志字段 options.LoggingFields = HttpLoggingFields.All; // 自定义筛选规则 options.AddFilter(context => { var requestPath = context.Request.Path; // 登录接口不记录请求体(避免密码被记录) if (requestPath.StartsWithSegments("/api/auth/login")) { return HttpLoggingFields.All & ~HttpLoggingFields.RequestBody; } // 令牌返回接口不记录响应体(避免API令牌泄露) else if (requestPath.StartsWithSegments("/api/auth/get-token")) { return HttpLoggingFields.All & ~HttpLoggingFields.ResponseBody; } // 其他接口保持全量记录 return HttpLoggingFields.All; }); });
二、屏蔽请求/响应中的敏感字段(保留其他内容)
如果需要保留大部分请求/响应内容,只屏蔽特定敏感字段(比如请求里的password、响应里的apiToken),可以自定义IHttpLoggingInterceptor来拦截并修改日志内容:
1. 实现自定义拦截器
public class SensitiveDataMaskingInterceptor : IHttpLoggingInterceptor { public async ValueTask OnLogRequestAsync(HttpLoggingInterceptorContext logContext) { // 仅当需要记录请求体时处理 if (!logContext.LoggingFields.HasFlag(HttpLoggingFields.RequestBody)) return; // 读取请求体内容 var originalBody = await new StreamReader(logContext.Request.Body).ReadToEndAsync(); // 重置流位置,避免后续中间件无法读取 logContext.Request.Body.Position = 0; // 用正则替换敏感字段(这里假设请求体是JSON格式) var maskedBody = Regex.Replace(originalBody, "\"password\":\"[^\"]*\"", "\"password\":\"***\""); // 将处理后的内容写回日志上下文 logContext.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(maskedBody)); } public async ValueTask OnLogResponseAsync(HttpLoggingInterceptorContext logContext) { // 仅当需要记录响应体时处理 if (!logContext.LoggingFields.HasFlag(HttpLoggingFields.ResponseBody)) return; // 读取响应体内容 var originalBody = await new StreamReader(logContext.Response.Body).ReadToEndAsync(); logContext.Response.Body.Position = 0; // 替换响应中的API令牌字段 var maskedBody = Regex.Replace(originalBody, "\"apiToken\":\"[^\"]*\"", "\"apiToken\":\"***\""); logContext.Response.Body = new MemoryStream(Encoding.UTF8.GetBytes(maskedBody)); } }
2. 注册拦截器
把自定义拦截器添加到HttpLogging配置中:
builder.Services.AddHttpLogging(options => { options.LoggingFields = HttpLoggingFields.All; // 添加自定义敏感字段屏蔽拦截器 options.Interceptors.Add<SensitiveDataMaskingInterceptor>(); });
三、结合两种方案的综合实践
实际场景中可以把两种方式结合:对高风险接口(如登录、令牌接口)直接屏蔽整个请求/响应体,对其他接口则只屏蔽敏感字段,既保证日志完整性又避免敏感数据泄露:
builder.Services.AddHttpLogging(options => { options.LoggingFields = HttpLoggingFields.All; // 针对特定端点屏蔽整段内容 options.AddFilter(context => { var path = context.Request.Path; if (path.StartsWithSegments("/api/auth/login")) { return HttpLoggingFields.All & ~HttpLoggingFields.RequestBody; } else if (path.StartsWithSegments("/api/auth/get-token")) { return HttpLoggingFields.All & ~HttpLoggingFields.ResponseBody; } return HttpLoggingFields.All; }); // 对其他接口屏蔽敏感字段 options.Interceptors.Add<SensitiveDataMaskingInterceptor>(); });
内容的提问来源于stack exchange,提问作者James Anderbard
相关产品推荐
相关产品推荐

