C# .NET 6 Serilog,如何在没有敏感数据的情况下使用 UseSerilogRequestLogging 记录请求/响应

Via*_*ans 6 c# security api serilog .net-6.0

我正在开发 .NET 6 API,并尝试使用 Serilog 记录所有用户操作。

我想做到这一点,而不必添加_logger.Info(...);用户请求和响应的每个端点。

在互联网上查看后,我发现可以使用UseSerilogRequestLogging(). 它工作得很好,但问题在于敏感数据。出于安全原因,某些数据(例如电子邮件、密码等)不应位于日志中。

所以问题是:如何记录所有用户请求和响应,同时出于安全原因隐藏敏感数据?

此 API 的一些代码:

获取日志中的数据:

app.UseHttpLogging()
    .UseSerilogRequestLogging();
Run Code Online (Sandbox Code Playgroud)
builder.Services.AddHttpLogging(logging =>
{
    logging.LoggingFields = HttpLoggingFields.All;
    logging.RequestHeaders.Add(HeaderNames.Accept);
    logging.RequestHeaders.Add(HeaderNames.ContentType);
    logging.RequestHeaders.Add(HeaderNames.ContentDisposition);
    logging.RequestHeaders.Add(HeaderNames.ContentEncoding);
    logging.RequestHeaders.Add(HeaderNames.ContentLength);

    logging.MediaTypeOptions.AddText("application/json");
    logging.MediaTypeOptions.AddText("multipart/form-data");

    logging.RequestBodyLogLimit = 4096;
    logging.ResponseBodyLogLimit = 4096;
});
Run Code Online (Sandbox Code Playgroud)

记录配置并尝试隐藏敏感数据:

builder.Host.UseSerilog((context, services, configuration) => configuration
    .ReadFrom.Configuration(context.Configuration)
    .ReadFrom.Services(services)
    .Enrich.FromLogContext()
    .Enrich.With<UserEnricher>()
    .Destructure.ByTransforming<AddUserDto>(_ => new AddUserDto()
    {
        UserName = _.UserName, UserDescription = _.UserDescription, Password = "****", Email = "****"
    })
    .Destructure.ByTransforming<UserLoginDto>(_ => new UserLoginDto()
    {
        UserName = _.UserName,
        Password = "****"
    })
    .Destructure.ByTransforming<JsonWebToken>(_ => new JsonWebToken("****")));
Run Code Online (Sandbox Code Playgroud)

具有敏感数据的端点:

[HttpPost("SignUp")]
[AllowAnonymous]
public async Task<IActionResult> SignUp(AddUserDto user)
{
    return Ok(await _userService.AddUser(user));
}

[HttpPost("SignIn")]
[AllowAnonymous]
public async Task<IActionResult> SignIn(UserLoginDto userLogin)
{
    if (await _userService.SignIn(userLogin))
        return Ok((await _jwtService.GenerateJwt((await _userService.GetUser(userLogin.UserName)).Id)).Token);
    return BadRequest(new BlogErrorResponse(nameof(InvalidRequestException),"Bad username or password."));
}
Run Code Online (Sandbox Code Playgroud)