C# 在DBContext上设置从Key Vault检索的连接字符串的正确方法是什么?

C# 在DBContext上设置从Key Vault检索的连接字符串的正确方法是什么?,c#,entity-framework,C#,Entity Framework,我创建了一个实体框架DBContext。当我这样做时,它将连接字符串放在下面的方法中 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { #warning To protect potentially sensitive information i

我创建了一个实体框架DBContext。当我这样做时,它将连接字符串放在下面的方法中

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            #warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
            optionsBuilder.UseSqlServer("REDACTED");
        }
    }
如您所见,代码中有一条关于连接字符串的警告消息。这是有道理的,但据我所知,该警告消息中的链接文章告诉我将其移动到appSettings.json文件中。这仍然是不安全的,因为连接字符串和数据库用户的密码将以明文形式存在

我已将连接字符串放置到密钥库中,并希望在运行时对其进行设置。正确的方法是什么?我曾考虑编辑DBContext类,将其作为属性,以便执行以下操作:

    public string ConnectionString { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer(ConnectionString);
        }
    }
然后在另一个类中执行以下操作:

       var secret_connection_string = GetFromKeyVault("DbContextConnectionString")
       using(var context = new MyDBContext() { ConnectionString = secret_connection_string }) { 
            //Do database stuff.
       }

这是一种正确的方法,还是会在以后导致其他问题?

如果您使用Azure,yes key vault就是一种方法。其他云服务也提供类似的秘密管理服务

策略是在第一次从密钥库/机密提供程序读取时在内存中实现某种缓存。这样,下次或代码的另一部分希望访问相同的连接字符串时,它将减少获取该连接字符串的时间


您可以使缓存过期,以便可以从密钥库中重新加载连接字符串或机密(如果愿意),这取决于您的最终决定。

您可以使用连接字符串的公共只读属性,并通过DbContext的构造函数进行设置,然后在
OnConfiguring
调用中引用此属性

将属性设置为只读可确保在实例化上下文后无法更改连接字符串。而在构造函数中设置它可以确保在调用
onconfigurang
时它可用

public class SomeDbContext: DbContext
{
    public string ConnectionString { get; } // read only property can be set in constructor

    public SomeDbContext(string connectionString)
    : base()
    {
        this.ConnectionString = connectionString;
    }        

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(ConnectionString);             
    }
}
然后您将实例化您的
DbContext
,如下所示

var secret_connection_string = GetFromKeyVault("DbContextConnectionString");
using(var context = new MyDBContext(secret_connection_string))
{ 
    //Do database stuff.
}