练习 - 在云原生应用程序中编辑敏感数据
你需要向订单过程添加一些记录。 你将使用 .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 格式的日志条目。 请注意,order.Total 值位于日志中,但 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 格式的日志条目。 请注意,order.Id 值仍然是空字符串,但 CustomerName 和 CustomerAddress 值现在为
*****.
。在“终端”窗口中,按 Ctrl+C 以停止应用。