练习 - 在云原生应用程序中编辑敏感数据

已完成

你需要向订单过程添加一些记录。 你将使用 .NET 的编修功能来确保敏感数据不会泄漏到日志中。

通过学习本练习,你将能够:

  • Microsoft.Extensions.Compliance.Redaction NuGet 包添加到每个项目。
  • 将编修服务添加到依赖项注入容器。
  • 在记录框架中启用编修。
  • 在订单过程中调用记录框架。
  • 为 EUII 数据添加自定义编修实现。
  • 选择要用于每种分类数据的编修实现。

添加编修服务

你的 codespace 或 Visual Studio Code 窗口应仍开着。 如果没有,请现在打开它。

  1. 在“终端”窗口中输入此命令:

    cd /workspaces/mslearn-dotnet-cloudnative/dotnet-compliance/eShopLite/Store/
    
  2. Microsoft.Extensions.Compliance.Redaction NuGet 包添加到项目:

    dotnet add package Microsoft.Extensions.Compliance.Redaction
    
  3. 在“资源管理器”窗格中,展开 dotnet-compliance/eShopLite/Store 文件夹,然后选择 Program.cs 文件。

  4. 在编辑器中,添加以下依赖项:

    using Microsoft.Extensions.Compliance.Classification;
    using Microsoft.Extensions.Compliance.Redaction;
    
  5. 向下滚动到第 19 行,在 Add redaction 注释下,将编修服务添加到依赖项注入容器:

    builder.Services.AddRedaction();
    

在记录框架中启用编修

  1. 在编辑器中,将此代码添加到第 AddRedaction() 行下方:

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

    上述代码会在记录框架中启用编修。

在订单过程中调用记录框架

  1. 在“资源管理器”窗格中,展开 dotnet-compliance/eShopLite/Store/Services 文件夹,然后选择 ProductService.cs 文件。

  2. 在编辑器中,在文件底部添加以下代码:

    public static partial class Log
    {
        [LoggerMessage(1, LogLevel.Information, "Placed Order: {order}")]
        public static partial void LogOrders(this ILogger logger, [LogProperties] Order order);
    }
    
  3. 在编辑器中,在 CreateOrder 任务中调用 LogOrders 方法:

    public async Task<bool> CreateOrder(Order order)
    {
        try
        {
            _logger.LogOrders(order);
    

    上述代码会调用 LogOrders 方法并为其传递当前订单信息。

测试新编修的记录

完成上述所有代码后,应用就可以使用默认的编修实现来编修 Order 信息。 现在,你将对此进行测试。

  1. 在底部的“终端”窗格中,转到 dotnet-compliance/eShopLite 文件夹

    cd ..
    
  2. 更新应用容器。

    dotnet publish /p:PublishProfile=DefaultContainer 
    
  3. 转到 dotnet-compliance 文件夹,并使用 Docker 启动应用

    cd ..
    docker compose up
    
  4. 选择“端口”选项卡,然后选择“前端(32000)”端口的“在浏览器中打开”地球图标

  5. 选择“产品”链接。 向购物篮添加一些产品。

  6. 选择“购买篮子”按钮。

  7. 在“终端”窗口中,按 Ctrl+F,在搜索字段中输入 "EventId":1,。

    frontend-1  | {"EventId":1,"LogLevel":"Information","Category":"Store.Services.ProductService","Message":"Placed Order: DataEntities.Order","State":{"Message":"Microsoft.Extensions.Logging.ExtendedLogger\u002BModernTagJoiner","{OriginalFormat}":"Placed Order: {order}","order.Total":209.94,"order.Products":"[\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022]","order":"DataEntities.Order","order.CustomerAddress":"","order.CustomerName":"","order.Id":""}}
    

    你应会看到此 JSON 格式的日志条目。 请注意,order.Total 值位于日志中,但 CustomerName 和 CustomerAddress 值是空字符串。

    默认情况下,如果你未指定编修实现,则编修引擎将使用 ErasingRedactor 实现来确保不会将敏感数据泄露到日志中。

  8. 在“终端”窗口中,按 Ctrl+C 以停止应用

添加自定义编修实现

现在,你将增强编修实现,对不同类型的数据使用不同的编修算法。 首先,你将添加一个新的自定义编修实现,它会将值替换为 *****

  1. 在“资源管理器”窗格中,展开 dotnet-compliance/eShopLite/DataEntities 文件夹,然后选择 Compliance.cs 文件。

  2. 在编辑器中,在文件底部添加以下代码:

    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;
        }
    }
    

    上述代码使 EShopCustomRedactor 编修方法可用于编修引擎。

选择要使用的编修实现

  1. 在“资源管理器”窗格中,展开 dotnet-compliance/eShopLite/Store 文件夹,然后选择 Program.cs 文件。

  2. 替换 builder.Services.AddRedaction(); 代码以提供编修引擎的配置:

    builder.Services.AddRedaction(configure =>
    {
        configure.SetRedactor<ErasingRedactor>(new DataClassificationSet(DataClassifications.EUPDataClassification));
        configure.SetRedactor<EShopCustomRedactor>(new DataClassificationSet(DataClassifications.EUIIDataClassification));
    });
    

    上述代码将编修引擎配置为专门为 EUP 数据使用 ErasingRedactor 实现,为 EUII 数据使用新的自定义 EShopCustomRedactor 实现。

测试新的编修实现

  1. 在“终端”窗口中,生成并运行应用:

    docker-compose up --build
    
  2. 选择“端口”选项卡,然后选择“前端 (32000)”端口的“在浏览器中打开”地球图标

  3. 选择“产品”链接。 向购物篮添加一些产品。

  4. 选择“购买篮子”按钮。

  5. 在“终端”窗口中,按 Ctrl+F,在搜索字段中输入 "EventId":1,。

    frontend-1  | {"EventId":1,"LogLevel":"Information","Category":"Store.Services.ProductService","Message":"Placed Order: DataEntities.Order","State":{"Message":"Microsoft.Extensions.Logging.ExtendedLogger\u002BModernTagJoiner","{OriginalFormat}":"Placed Order: {order}","order.Total":269.88,"order.Products":"[\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022,\u0022DataEntities.Product\u0022]","order":"DataEntities.Order","order.CustomerAddress":"*****","order.CustomerName":"*****","order.Id":""}}
    

    你应会看到此 JSON 格式的日志条目。 请注意,order.Id 值仍然是空字符串,但 CustomerName 和 CustomerAddress 值现在为 *****.

  6. 在“终端”窗口中,按 Ctrl+C 以停止应用