PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Saturday, November 5, 2022

[FIXED] How to get connection string for database from appsettings.json for local and azure key vault for production?

 November 05, 2022     appsettings, azure-keyvault, azure-managed-identity, connection-string, environment-variables     No comments   

Issue

In local I need to connect to database using appsettings.json but in other environments like dev,staging and prod need to get connection string for db from azure key vault.In launchsettings.json I have set environment to local and when I run the project in local I am getting error in program.cs as 'The ConfigureServices method must either be parameterless or take only one parameter of type IServiceCollection.'Please let me know what is the issue here or how to fix it

appsettings.json

{
  "KeyVault": {
    "Vault": "Bookskv"
  },
  "MongoConnection": {
  "ConnectionString": "<set by keyvault>",
    "Database": "Books"
  },
  "MongoLocal": {
    "ConnectionString": "mongodb:localhost:1230",
    "Database": "Books"
  }
}

Program.cs

  public static IWebHost CreateWebHostBuilder(string[] args)
        {
            return WebHost.CreateDefaultBuilder(args)
               .ConfigureAppConfiguration((ctx, builder) =>
                 {
                     var keyName = string.Empty;
                     if (ctx.HostingEnvironment.EnvironmentName!="Local")
                     {
                         var keyVaultEndpoint = GetKeyVaultEndpoint();
                         if (!string.IsNullOrEmpty(keyVaultEndpoint))
                         {
                             var azureServiceTokenProvider = new AzureServiceTokenProvider();
                             var keyVaultClient = new KeyVaultClient(
                                 new KeyVaultClient.AuthenticationCallback(
                                     azureServiceTokenProvider.KeyVaultTokenCallback));
                             if(ctx.HostingEnvironment.EnvironmentName=="Development")
                             {
                                  keyName = "BooksdevDb";
                             }
                             else if(ctx.HostingEnvironment.EnvironmentName == "Production")
                             {
                                  keyName = "BooksprodDb";
                             }
                             var secretBundle =  keyVaultClient.GetSecretAsync("https://Bookskv.vault.azure.net/secrets/{keyName}").Result;
                             var secret = secretBundle.Value;                          
                           
                             builder.AddAzureKeyVault(
                                 keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());
                         }
                   
                     }                    
                 }
              ).UseUrls("http://localhost:44315")
               .UseKestrel()
               .UseIISIntegration()
               .UseIIS()
               .UseStartup<Startup>()
               .Build();
        }
        private static string GetKeyVaultEndpoint() => "https://Bookskv.vault.azure.net";

    }

Startup.cs

  services.Configure<Settings>(options =>
            {

                if (env.IsDevelopment() || env.IsStaging() || env.IsProduction()) 
                {
                    options.ConnectionString = Configuration.GetSection("MongoConnection:ConnectionString").Value;
                    options.Database = Configuration.GetSection("MongoConnection:Database").Value;
                }
                else
                {
                    options.ConnectionString = Configuration.GetSection("MongoLocal:ConnectionString").Value;
                    options.Database = Configuration.GetSection("MongoLocal:Database").Value;
                }
            });

Settings.cs

 public class Settings
    {
        public string ConnectionString;
        public string Database;
    }

Solution

I have already implemented same thing in my project. Donot need to write too much code.

Before Implementing/Following below steps. DO THE STEPS WHICH I MENTIONED IN ANSWER OF THIS QUESTION

  1. Create Two AppSettings :- appsettings.Development.json and appsettings.Production.json

appsettings.Development.json

{
   "DBConnection": "xyz"
}

appsettings.Production.json

{
   "KeyVaultName": "keyvalutname"
}
  1. Add/Install Nuget Package for KeyVault

Azure.Security.KeyVault.Secrets

  1. Create KeyVaultManagement class
public class KeyVaultManagement
   {
      private readonly IConfiguration _config;

      public KeyVaultManagement(IConfiguration config)
      {
        _config= config;
      }

      public SecretClient SecretClient
      {
        get
         {
            return new SecretClient(
                             new Uri($"https://{this._config["KeyVaultName"]}.vault.azure.net/"),
                             new DefaultAzureCredential()) ;
         }
       }
  }
  1. Write the below code in Program.cs
.ConfigureAppConfiguration((context, config) =>
{
   var builtConfig = config.Build();
   if (!context.HostingEnvironment.IsDevelopment())
   {
     config.AddAzureKeyVault(new KeyVaultManagement(builtConfig).SecretClient, new KeyVaultSecretManager());
   }
});
  1. Write the below where need to fetch secret.
var valueofSecret = configuration["DBConnection"];

configuration is IConfiguration

IF YOUR APPLICATION IS NOT APP SERVICE OR IT IS DEVELOPED IN .NET FRAMEWORK

Then Implement KEYVAULT using Certificate

  1. Install Same Nuget Packages

  2. Write the below code in Program.cs. Might need to add package or namespace to use certificate classes

.ConfigureAppConfiguration((context, config) =>
{
   var root = config.Build();
   var KeyVaultName = root["KeyVaultName"];
   var Uri = new Uri($"https://{KeyVaultName}.vault.azure.net/");
   var x509Certifcate = CertifcateHelper.GetCertificate(root["Thumprint"],"KeyVaultCertificate");
   
     config.AddAzureKeyVault(Uri , new ClientCertificateCredential(root["ClientTenantId"], root["ClientAppId"], x509Certifcate));
});

  1. Add the below lines in APPSetting

appsettings.Development.json

{
   "KeyVaultName": "keyvalutname",
   "ClientTenantId": "Get from azure and paste here",
   "ClientAppId": "Get from azure and paste here",
   "Thumbprint": "Get from keyvalut certificate in azure and paste here";
}
  1. Write the below where need to fetch secret.
var valueofSecret = configuration["DBConnection"];


Answered By - Pradeep Kumar
Answer Checked By - David Goodson (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing