我们使用 Azure 密钥保管库来存储机密(如密码)。我们实现了一个名为
KeyVaultClient
的客户端,它从 Azure Key Vault 请求所需的机密。 Key Vault 中有一个秘密,在 Startup.cs 类的配置过程中需要它。这是代码:
public class Startup
{
[...]
public void ConfigureServices(IServiceCollection services)
{
[...]
// register DI and dependent configuration
services.AddSingleton<IKeyVaultClient, KeyVaultClient>().Configure<KeyVaultClientSettings>(Configuration.GetSection(KeyVaultClientSettings.Section));
// code which resolves IKeyVaultClient, because we need to request a secret
var serviceProvider = services.BuildServiceProvider();
var keyVaultClient = serviceProvider.GetService<IKeyVaultClient>();
var secretName = "My Secret Name";
var secret = keyVaultClient.GetSecret(secretName);
// Our custom extension method which authenticates this app via the secret
services.AddFrontendAuthentication(secret);
[...]
}
}
为 DI 注册 IKeyVaultClient 并直接解析它,对我来说看起来无论如何都很脏。让代码在其他项目中更加干净和可重用的最佳实践是什么?
通常,依赖注入友好的库允许传递一个需要
IServiceProvider
进行配置的函数。
Options 模式就是一个示例。
如果您控制
AddFrontendAuthentication
方法,我建议重构前端身份验证服务以接受 IOptions<FrontendAuthenticationOptions>
。
然后调用者可以单独配置它们(或者 AddFrontendAuthentication
可以为他们做这件事)。
喜欢:
public class Startup
{
[...]
public void ConfigureServices(IServiceCollection services)
{
[...]
// register DI and dependent configuration
services.AddSingleton<IKeyVaultClient, KeyVaultClient>();
services.Configure<KeyVaultClientSettings>(Configuration.GetSection(KeyVaultClientSettings.Section));
services.AddOptions<FrontendAuthenticationOptions>()
.Configure<IKeyVaultClient>((options, keyVaultClient) => {
var secretName = "My Secret Name";
options.Secret = keyVaultClient.GetSecret(secretName);
});
services.AddFrontendAuthentication();
[...]
}
}