在云原生应用程序中编修敏感数据

已完成

应用程序中的编修通常在日志消息和遥测上完成。 它还可以用于其他场景,如指标中的维度编修,或中间件中的标头数据。

.NET 记录框架提供了一种简单的方法来编修日志消息中的数据。 Microsoft.Extensions.Compliance.Abstractions 包增强了日志记录,以包含编修数据的 Redactor 类。

什么是编修?

编修是从消息中删除敏感信息的过程。 例如,你可能希望从日志消息中编修用户的名称。 或者,你可能想要从遥测事件中编修用户的 IP 地址。

最简单的编修是清除值,并返回变量的空字符串。 此行为默认发生,因为 ErasingRedactor 是默认回退编修器。 Microsoft 包括一个 HMACSHA256Redactor 类,可用于使用哈希函数编修数据。 如果想要编修数据,但仍然能够跨多个日志语句关联日志消息,则 HMAC 编修非常有用。 最后一个选项是提供自己的编修函数,如果想要使用自定义算法编修数据,这非常有用。

例如,你希望通过将值替换为 *****,更清楚地说明该值已被编修。

如何在云原生应用程序中编修数据

你的组织云原生应用可能会编写日志并在多个项目中创建遥测。 例如,它可以从数据库服务、Web 应用或它使用的任何其他 API 编写日志。 根据日志记录的类型,需要将编修服务添加到每种类型。

在应用中启用编修需要执行四个步骤:

  1. Microsoft.Extensions.Compliance.Redaction NuGet 包添加到每个项目。
  2. 将编修服务添加到依赖项注入容器。
  3. 选择要用于每种类型的分类数据的编修实现。
  4. 在记录框架中启用编修。

将编修服务添加到依赖项注入容器

以下示例适用于 Blazor WebAssembly 应用。 此过程与其他类型的应用类似,但代码略有不同,具体取决于依赖项注入容器的配置方式。

program.cs 文件中,添加以下依赖项:

using Microsoft.Extensions.Compliance.Classification;
using Microsoft.Extensions.Compliance.Redaction;

通过上述包,可以使用以下代码将编修服务添加到依赖项注入容器:

builder.Services.AddRedaction();

选择要用于每种类型的分类数据的编修实现

AddRedactor 方法可以包含 RedactorOptions 参数。 通过此参数,可以指定要用于每个数据分类的编修实现。

例如,以下代码指定 HMACSHA256Redactor 应用于 EUII 数据。

builder.Services.AddRedaction(configure =>
{
    // Configure to use the HMAC redactor
    configure.SetHmacRedactor(configureHmac =>
    {
        // This key should be fetched from keyvault or some other secure store.
        configureHmac.Key = "thisisadummykeythatshouldbereplacedwithakeyfromakeystore";
        // Some discriminator to differentiate between different deployments of a service.
        configureHmac.KeyId = 1;

    }, new DataClassificationSet(DataClassifications.EUIIDataClassification));
});

注意

HMAC 编修器算法是试验性的,因此,如果使用它,则需要禁用编译器警告。 使用 #pragma warning disable EXTEXP0002#pragma warning restore EXTEXP0002 包围上述代码,使你能够编译项目。

可以将多个编修实现添加到 RedactorOptions 参数。 例如,以下代码会为 EUPI 数据添加自定义编修器。

builder.Services.AddRedaction(configure =>
{
    // Configure to use the HMAC redactor for EUII data
    configure.SetHmacRedactor(configureHmac =>
    {
        // This key should be fetched from keyvault or some other secure store.
        configureHmac.Key = "thisisadummykeythatshouldbereplacedwithakeyfromakeystore";
        // Some discriminator to differentiate between different deployments of a service.
        configureHmac.KeyId = 1;

    }, new DataClassificationSet(DataClassifications.EUIIDataClassification));

    // Configure a custom redactor for EUPI data
    configure.SetRedactor<EShopCustomRedactor>(new DataClassificationSet(DataClassifications.EUPIDataClassification));
});

在记录框架中启用编修

下一步是在记录框架中启用编修。 为此,请将 .EnableRedaction 属性设置为应用程序日志记录生成器。 对于示例应用,代码为:

builder.Services.AddLogging(logging => 
{
    logging.EnableRedaction();
    logging.AddJsonConsole(); //Enable structure logs on the console to view the redacted data.
});

使用上述代码,可以创建使用编修服务的新记录器。 在要将订单信息写入日志的位置,实现新的 LogOrders 记录器。

public static partial class Log
{
    [LoggerMessage(1, LogLevel.Information, "Write the Order data formatted as JSON: {order}")]
    public static partial void LogOrders(this ILogger logger, [LogProperties] Order order);
}

创建自定义编修实现

Microsoft 允许你创建自定义编修实现。 如果要使用自己的算法编修数据,需要使用自定义编修。 让我们实现一个自定义编修器,其将敏感数据替换为 *****

自定义编修器需要实现 Redactor 类。 类需要实现两种方法:

public class EShopCustomRedactor : Redactor
{
    private const string Stars = "*****";

    public override int GetRedactedLength(ReadOnlySpan<char> input) => Stars.Length;

    public override int Redact(ReadOnlySpan<char> source, Span<char> destination)
    {
        Stars.CopyTo(destination);
        return Stars.Length;
    }
}

在我们的示例 eShopLite 体系结构中,可以将此类添加到数据分类代码下方 Compliance.cs 中的 DataEntities 项目中。