2017-09-20 2 views
1

엔티티 프레임 워크 용 웹 API 연결 문자열을 저장하기 위해 Azure Key Vault를 사용하려고합니다. 이상적으로는 주요 볼트 너겟 패키지를 데이터 액세스 코드와 연결하지 않는 것이 좋습니다.엔티티 프레임 워크 "Azure Key Vault"엔티티 프레임 워크 "DefaultConnection"앱 설정

public MyDbContext() : base("DefaultConnection") 
{ . . . } 

public MyDbContext(string connectionString) : base(connectionString) 
{ . . . } 

내 코드는 웹 설정에서 연결 문자열을 가져옵니다 매개 변수가없는 생성자를 사용합니다 : 내 dbContext 클래스는 두 개의 생성자가 있습니다. 주입을 사용하는 솔루션을 금지하는 MyDbContext 객체를 인스턴스화하는 곳이 있습니다.

내가했다 경로는 연결 문자열 로케이터 내 dbcontext에 정적 속성을 설정하는 것입니다

public interface IConnectionStringLocator 
{ string Get(); } 

public class DefaultConnectionStringLocator : IConnectionStringLocator 
{ 
    public string Get() 
    { 
     return "DefaultConnection"; 
    } 
} 

public static IConnectionStringLocator ConnectionStringLocator { get; set; } = 
    new DefaultConnectionStringLocator(); 

내 웹 API 프로젝트는 키 볼트 비밀을 검색하는 nuget 패키지가 있습니다. 그래서 내 Global.asax 파일에 나는 이것을 가지고있다 :

protected void Application_Start() 
{ 
    MyDbContext.ConnectionStringLocator = new ConnectionStringLocator("DefaultConnection"); 
} 

public class ConnectionStringLocator : IConnectionStringLocator 
{ 
    private readonly string _connectionStringName; 

    public ConnectionStringLocator(string connectionStringName) 
    { 
     this._connectionStringName = connectionStringName; 
    } 
    public string Get() 
    { 
     var keyVaultName = WebConfigurationManager.AppSettings.Get("KeyVaultName"); 
     if (keyVaultName == "develop") 
      return _connectionStringName; 
     else 
     { 
      AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); 
      var keyVaultClient = 
       new KeyVaultClient(
        new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); 
      var defaultConnectionSecret = 
       keyVaultClient.GetSecretAsync($"https://{keyVaultName}.vault.azure.net/secrets/{this._connectionStringName}"); 

      return defaultConnectionSecret.Result.Value; 
     } 
    } 
} 

나는 이것을 출판했으나 제대로 작동하지 않는다.

또 다른 옵션은이 문서 https://blog.falafel.com/keeping-secrets-with-azure-key-vault/을 따르는 것이지만 데이터 액세스로 KeyVault API 패키지를 연결해야합니다.

의견 및 방향을 찾고 있습니다. SQL Server에 연결 문자열을 통해 액세스하지 않고도 응용 프로그램 설정을 온라인으로 볼 수있는 푸른 색 관리자를 보유 할 수 있기 때문에 키 저장소를 사용하려는 이유가 있다고 덧붙여 야합니다. 새로운 MSI의 구현

KeyVault 자원 : https://github.com/Azure-Samples/app-service-msi-keyvault-dotnet/

답변

0

여기에 내가 그것에 경우 다른 사람 비틀 거림,이 해결 방법은 다음과 같습니다.

먼저 키 볼트에서 값을 가져 오려고 시도하지만 WebConfigurationManager를 사용하여 응용 프로그램 설정을 읽는 ConfigurationManager 클래스가 만들어졌습니다.

public static class ConfigurationManager 
{ 
    public static string KeyVaultName => WebConfigurationManager.AppSettings.Get("KeyVaultName"); 
    private static readonly Dictionary<string, string> ConfigurationCache = new Dictionary<string, string>(); 
    private static SecretBundle GetSecret(string secretName, string vaultName = null) 
    { 
     AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); 
     var keyVaultClient = 
      new KeyVaultClient(
       new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); 
     var secretUri = $"https://{vaultName ?? KeyVaultName}.vault.azure.net/secrets/{secretName}"; 
     var secret = keyVaultClient.GetSecretAsync(secretUri); 
     return secret.Result; 
    } 

    public static string GetAppSettingValue(string secretName, string vaultName = null) 
    { 
     vaultName = vaultName ?? KeyVaultName; 
     string key = $"{vaultName}:{secretName}"; 
     string value; 

     if (ConfigurationCache.TryGetValue(key, out value)) 
      return value; 

     if (string.IsNullOrEmpty(vaultName) || vaultName == "develop") 
     { 
      value = WebConfigurationManager.AppSettings.Get(secretName); 
      ConfigurationCache.Add(key, value); 
      return value; 
     } 

     var secret = GetSecret(secretName); 
     value = secret.Value; 
     ConfigurationCache.Add(key, value); 
     return value; 
    } 

    public static void SetAppSettingValue(string secretName, string value, string vaultName = null) 
    { 
     vaultName = vaultName ?? KeyVaultName; 
     string key = $"{vaultName}:{secretName}"; 

     if (ConfigurationCache.ContainsKey(key)) 
      ConfigurationCache[key] = value; 
     else 
     { 
      WebConfigurationManager.AppSettings[key] = value; 
      ConfigurationCache.Add(key, value); 
     } 


    } 
    public static string GetConnectionStringValue(string secretName, string vaultName = null) 
    { 
     vaultName = vaultName ?? KeyVaultName; 
     string key = $"{vaultName}:{secretName}"; 
     string value; 

     if (ConfigurationCache.TryGetValue(key, out value)) 
      return value; 

     if (string.IsNullOrEmpty(vaultName) || vaultName == "develop") 
     { 
      value = WebConfigurationManager.ConnectionStrings[secretName].ConnectionString; 
      ConfigurationCache.Add(key, value); 
      return value; 
     } 

     var secret = GetSecret(secretName); 
     value = secret.Value; 
     ConfigurationCache.Add(key, value); 
     return value; 
    } 
} 

내 dbcontext 클래스에서 나는 Configurationmanager.GetConnectionStringValue ("DefaultConnection")를 호출합니다.

public MyDbContext() 
     : base(ConfigurationManager.GetConnectionStringValue("DefaultConnection")) 
    {...}