Reputation: 227
I've created an Entity Framework DbContext which I initialize in the Program (Startup.cs is not needed anymore in .NET 6). The connectionstring is dependent on a SQL password inside Azure Key Vault. So the registration of both Key Vault and DbContext are done in the Program.cs . But how do I retrieve the secret from KeyVault to put inside the connectionstring? I do not want to manually create a SecretClient instance here, but have it injected somehow...
I now have:
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(new Uri(builder.Configuration.GetSection("KeyVault:VaultUri").Value))
.WithCredential(new DefaultAzureCredential());
});
builder.Services.AddDbContext<MyContext>(options =>
{
// How to get an instance of SecretClient here via DI? I need to call the serviceClient.GetSecret("sql-password") here to put it inside the connectionstring
// var sqlPassword = builder.Configuration.GetSection("sql-password").Value <-- also returns null
var sqlPassword = "get-this-password-from-key-vault";
options.UseSqlServer(string.Format(builder.Configuration.GetConnectionString("MyConnectionString"), sqlPassword));
});
I've read on several blogs that when you add the SecretClient to the Services, it should read all the secrets and add them to the builder.Configuration , meaning you should be able to read it like this:
var sqlPassword = builder.Configuration["sql-password"]
or
var sqlPassword = builder.Configuration.GetSection("sql-password").Value
Both of them return null . So I'm running out of options here. If anyone has a solution for this simple problem, I'm more than grateful. Thanks!
PS: I know for a fact the Key Vault is registered successfully; when I use the ServiceClient within a controller, I can successfully retrieve the secret.
Upvotes: 6
Views: 15853
Reputation: 3292
You can register a SecretClient
a number of ways described at https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/extensions/Microsoft.Extensions.Azure/README.md. In this case, you could even instantiate a SecretClient
, add it to the configuration builder, then use it directly. Or once registered to the confguration builder, refer to the configuration value you want that is stored in a SecretClient
:
var builder = WebApplication.CreateBuilder(args);
var keyVaultEndpoint = new Uri(Environment.GetEnvironmentVariable("VaultUri"));
builder.Configuration.AddAzureKeyVault(keyVaultEndpoint, new DefaultAzureCredential());
// Add services to the container.
builder.Services.AddDbContext<MyContext>(options =>
{
var sqlPassword = builder.Configuration["secret-password"];
options.UseSqlite(string.Format(builder.Configuration.GetConnectionString("MyConnectionString"), sqlPassword));
});
In Key Vault, just add a secret named "secret-password" in this case.
Upvotes: 8