Maxime Rossini
Maxime Rossini

Reputation: 3879

Setup data protection API depending on IConfiguration

I have a .NET 6 web application that can run on the cloud (AWS Lambda) and on a physical server. I want to setup data protection differently depending on the current environment. My initial thought was to use the application configuration:

// Program.cs

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
// [Omitted: setup builder.Configuration]
// [Omitted: setup builder.Services]
ConfigureDpApi(builder);

WebApplication app = builder.Build();
// [Omitted: setup app pipeline]

app.Run();

static void ConfigureDpApi(WebApplicationBuilder builder)
{
    AppConfiguration appConfig = builder.Configuration.Get<AppConfiguration>();
    if (appConfig.EnvironmentType == "AWS")
    {
        builder.Services.AddDataProtection()
            .SetApplicationName(applicationName: "myapp")
            .PersistKeysToAWSSystemsManager(parameterNamePrefix: "/myapp/api/DataProtection");
    }
    else if (appConfig.EnvironmentType == "ON_PREMISE")
    {
        var directoryInfos = new DirectoryInfo(appConfig.KeysFolder);
        var certificate = new X509Certificate2(appConfig.CertificatePath, appConfig.CertificatePassword);
        builder.Services.AddDataProtection()
            .SetApplicationName(applicationName: "myapp")
            .PersistKeysToFileSystem(directoryInfos)
            .ProtectKeysWithCertificate(certificate);
    }
    else
    {
        // No DPAPI (local development, tests)
    }
}

My issue with this method is that it fails with the integration tests, because the test project overrides the configuration source after dependencies have been configured:

// Test API client initialization
var factory = new WebApplicationFactory<Program>();
var apiClient = factory
    .WithWebHostBuilder(builder =>
    {
        // This line runs BEFORE Program.ConfigureDpApi()
        builder.ConfigureAppConfiguration((hostingContext, config) =>
        {
            // This line runs AFTER Program.ConfigureDpApi()
            config.Sources.Clear();
            config.SetBasePath(Directory.GetCurrentDirectory());
            config.AddJsonFile("appsettings.tests.json", optional: false);
        });
    })
    .CreateClient();

I'm stuck in this situation where I need my test configuration overrides to be available before DPAPI is setup (which happens during the WebHostBuilder configuration), which looks impossible to do (with reason).

Is there a way to configure DPAPI after my test project has overridden the configuration sources, meaning after WebApplicationBuilder.Build() has been called? Or should I give up on using IConfiguration altogether for this task and use a simpler method such as environment variables?

Upvotes: 1

Views: 98

Answers (0)

Related Questions