如何在我的 DI 容器中使用 IDataProtectionProvider 编写测试?

How do I write tests with IDataProtectionProvider in my DI container?

编辑 我最初问的问题是“JsonSerializer.Serialize throws 'Server failed to authenticate the request.' 如何防止 JsonSerializer 在单元测试中使用加密?”

然后我意识到我在被序列化的模型中使用了身份验证。抱歉这个可怜的问题。我编辑了问题。也许有人会发现我发现了一条奇怪的错误消息并解决了它很有用。

原题: 我正在将代码从本地迁移到 Azure。起初我删除了使用本地证书的加密。是时候把它放回去了,但是是以 Azure 的方式。我正在尝试使用 Azure Key Vault 保护密钥,如 https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-3.1 中所述。首先,我将其添加到 Startup.cs 中的 ConfigureServices:

using Microsoft.AspNetCore.DataProtection;
...
services.AddDataProtection()
    .PersistKeysToAzureBlobStorage(new Uri("https://ddd.blob.core.windows.net/ddd-dev-keystore?redacted"));

由于日志记录代码,我的一些测试失败了:

_logger.LogDebug("Model is {model}", JsonSerializer.Serialize(model));

该特定型号未加密,不需要接触任何加密/解密代码。稍后我会有一些数据需要加密,但我需要对此进行控制。

如何防止 JsonSerializer 使用加密?

编辑 忘了我把这个添加到有问题的模型中了:

public class MyModel
{
    private readonly IDataProtector _dataProtector;

    public MyModel(IDataProtectionProvider dataProtectionProvider, ...)
    {
        _dataProtector = dataProtectionProvider.CreateProtector(Models.MyPlan.EncryptionPurpose);
    ...
    }

至此,部分谜团解开了。这个问题一下子就简单多了。现在 - 如何在我的 DI 容器中使用 IDataProtectionProvider 编写测试?亲爱的朋友们,这已经在其他地方得到了回答。

也很有帮助。

我通过将此代码添加到测试工具启动解决了这个问题

public class CustomTestWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
    protected override IWebHostBuilder CreateWebHostBuilder()
    {
        return WebHost.CreateDefaultBuilder<TStartup>(null);
    }
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices((context, services) =>
        {
            services.AddSingleton<IDataProtectionProvider, EphemeralDataProtectionProvider>();
        }
    }
}

请注意最里面的一行,上面写着 AddSingleton 并且我添加了一个 IDataProtectionProvider?这就是魔法。它将真正的提供商替换为不访问 Azure 或任何其他密钥存储的提供商。

序列化模型是否使其加密还有待观察,但测试现已通过。