练习 - 在云原生应用程序中编修敏感数据
需要向订单过程添加一些日志记录。 你将使用 .NET 的修订功能来确保敏感数据不会泄漏到日志中。
通过学习本练习,你将能够:
- 将
Microsoft.Extensions.Compliance.Redaction
NuGet 包添加到每个项目。 - 将编辑服务添加到依赖注入容器中。
- 在记录框架中启用编修。
- 在处理订单时调用日志框架。
- 为 EUII 数据添加自定义修订实现。
- 选择要用于每种类型的分类数据的修订实现。
添加编辑服务
你仍应打开 codespace 或 Visual Studio Code 窗口。 如果没有,请现在打开它。
在“终端”窗口中输入此命令:
cd /workspaces/mslearn-dotnet-cloudnative/dotnet-compliance/eShopLite/Store/
将
Microsoft.Extensions.Compliance.Redaction
NuGet 包添加到项目:dotnet add package Microsoft.Extensions.Compliance.Redaction
在 “资源管理器 ”窗格中,展开 dotnet-compliance/eShopLite/Store 文件夹,然后选择 Program.cs 文件。
在编辑器中,添加以下依赖项:
using Microsoft.Extensions.Compliance.Classification; using Microsoft.Extensions.Compliance.Redaction;
向下滚动到第 19 行,在
Add redaction
注释下,将修订服务添加到依赖项注入容器:builder.Services.AddRedaction();
在日志记录框架中启用隐匿功能
在编辑器中,将此代码添加到行
AddRedaction()
下方:builder.Services.AddLogging(logging => { logging.EnableRedaction(); logging.AddJsonConsole(); //Enable structure logs on the console to view the redacted data. });
上述代码在日志记录框架中开启编辑功能。
在处理订单时调用日志记录框架
在 “资源管理器 ”窗格中,展开 dotnet-compliance/eShopLite/Store/Services 文件夹,然后选择 ProductService.cs 文件。
在编辑器中,在文件底部添加以下代码:
public static partial class Log { [LoggerMessage(1, LogLevel.Information, "Placed Order: {order}")] public static partial void LogOrders(this ILogger logger, [LogProperties] Order order); }
在编辑器中,在
CreateOrder
任务中调用LogOrders
方法。public async Task<bool> CreateOrder(Order order) { try { _logger.LogOrders(order);
上述代码调用
LogOrders
该方法并传递当前顺序信息。
测试新编修的记录
完成上述所有代码后,应用可以使用默认的修订实现来编辑 Order
信息。 现在,你将对此进行测试。
在底部的 “终端 ”窗格中,转到 dotnet-compliance/eShopLite 文件夹。
cd ..
更新应用容器。
dotnet publish /p:PublishProfile=DefaultContainer
转到 dotnet-compliance 文件夹,并使用 Docker 启动应用:
cd .. docker compose up
选择“端口”选项卡,然后为前端(32000)端口选择在浏览器中打开地球图标。
选择 “产品 ”链接。 向购物篮添加一些产品。
选择“ 购买篮” 按钮。
在终端窗口中,按 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 格式的日志条目。 请注意 订单。总 值位于日志中,但 CustomerName 和 CustomerAddress 值是空字符串。
默认情况下,如果未指定修订实现,则编修引擎将使用
ErasingRedactor
实现来确保不会泄露敏感数据到日志中。在 终端 窗口中,按 Ctrl+C 停止应用。
添加自定义编辑实现
现在,你将增强修订实现,以对不同类型的数据使用不同的编修算法。 首先,你将添加一个新的自定义修订实现,该实现将值替换为 *****
。
在 “资源管理器 ”窗格中,展开 dotnet-compliance/eShopLite/DataEntities 文件夹,然后选择 Compliance.cs 文件。
在编辑器中,在文件底部添加以下代码:
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
编修方法可用于编修引擎。
选择使用哪种编辑实现
在 “资源管理器 ”窗格中,展开 dotnet-compliance/eShopLite/Store 文件夹,然后选择 Program.cs 文件。
替换
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
实现。
测试新的编辑实现
在 终端 窗口中,生成并运行应用:
docker-compose up --build
选择“端口”选项卡,然后为前端(32000)端口选择在浏览器中打开地球图标。
选择 “产品 ”链接。 向购物篮添加一些产品。
选择“ 购买篮” 按钮。
在终端窗口中,按 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 格式的日志条目。 请注意 订单。ID 值仍然是空字符串,但 CustomerName 和 CustomerAddress 值现在为
*****.
在 终端 窗口中,按 Ctrl+C 停止应用。