如何从 Azure KeyVault 中获取连接字符串?
How to get connection string out of Azure KeyVault?
假设的网站当前使用以下方式连接:
public SqlConnection CreateConnection()
{
DbConnection connection = new SqlConnection();
connection.ConnectionString = GetConnectionString();
connection.Open();
return connection;
}
神奇的连接字符串存储在web.config
:
String GetConnectionString()
{
//Get the connection string info from web.config
ConnectionStringSettings cs = ConfigurationManager.ConnectionStrings["db"];
if (cs == null)
throw new Exception("Could not locate DB connection string");
return cs.ConnectionString;
}
现在我想将连接字符串从 web.config 文件移到 Azure KeyVault 中。您如何从 Azure 密钥保管库中检索任何内容?
String GetConnectionString()
{
//Get the connection string info from Azure KeyVault
String connectionString = GetAzureSecret("dbConnectionString");
if (String.IsNullOrWhitespace(connectionString)
throw new Exception.Create("Could not connection string of Azure Key Vault");
return connectionString;
}
除了我刚刚制作了易于使用的 Azure API。 实际api是什么?
未经测试的尝试
string GetAzureSecret(string key)
{
KeyVaultClient vault = new KeyVaultClient();
vault.OnAuthenticate += VaultClientAuthenticate;
var sec = await vault.GetSecretAsync(Key);
return sec.Value;
}
public static async Task<string> VaultClientAuthenticate(string authority, string resource, string scope)
{
String clientID = "8675209";
String clientSecret = "correct battery horse pencil";
var authContext = new AuthenticationContext(authority);
ClientCredential clientCred = new ClientCredential(clientID, clientSecret);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);
if (result == null)
throw new Exception("Could not acquire token");
return result.AccessToken;
}
红利阅读
- MSDN Forums: Storing sql connection string passwords in Key Vault for my Cloud Services
- Easily switching ConnectionStrings on publish to Azure
What is the actual api?
我们可以使用 GetSecret API 来获取值。
准备:
Registry Azure Active Directory application and assign Role
步骤:
1.Create KeyVault 并从 Azure 门户添加机密
2.Config 访问策略
3.Get 访问令牌
var context = new AuthenticationContext("https://login.windows.net/" + tenantId);
ClientCredential clientCredential = new ClientCredential(appId, secretKey);
var tokenResponse =await context.AcquireTokenAsync("https://vault.azure.net", clientCredential);
var accessToken = tokenResponse.AccessToken;
return accessToken;
注意:Keyvault 的资源是https://vault.azure.net
4.Test 使用 Fiddler
我们也可以使用 SDK 轻松做到这一点:
1.Create 一个控制台项目和一个 Utils.cs 文件
public static string EncryptSecret { get; set; }
static string appId = "Application ID";
static string secretKey = "Secert key";
static string tenantId = "TenantId";
public static async Task<string> GetAccessToken(string azureTenantId,string azureAppId,string azureSecretKey)
{
var context = new AuthenticationContext("https://login.windows.net/" + tenantId);
ClientCredential clientCredential = new ClientCredential(appId, secretKey);
var tokenResponse =await context.AcquireTokenAsync("https://vault.azure.net", clientCredential);
var accessToken = tokenResponse.AccessToken;
return accessToken;
}
2.Add 跟随主函数中的代码进行测试。
packages.config 文件
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Hyak.Common" version="1.0.2" targetFramework="net452" />
<package id="Microsoft.Azure.Common" version="2.0.4" targetFramework="net452" />
<package id="Microsoft.Azure.Common.Dependencies" version="1.0.0" targetFramework="net452" />
<package id="Microsoft.Azure.KeyVault" version="1.0.0" targetFramework="net452" />
<package id="Microsoft.Bcl" version="1.1.9" targetFramework="net452" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net452" />
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net452" />
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.13.9" targetFramework="net452" />
<package id="Microsoft.Net.Http" version="2.2.22" targetFramework="net452" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" />
</packages>
我们还可以从 document.
提到的 CtrlDot 获取更多信息
2020 年 8 月更新
现在可以通过 Key Vault 引用以零自定义代码从 App Service 调用 Key Vault,这是一种低调的方式。
https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references
从 Key Vault 填充值的应用程序设置示例:
@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931)
如果您不想要版本标识符:
@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)
您需要先在您的应用服务实例和 Key Vault 之间设置托管标识才能使用 Key Vault 引用。
我不反对 Key Vault(我认为它是一个很棒的产品!),但我情不自禁地认为你过度设计了它。
我会简单地使用内置 Application Settings functionality in Azure App Service:
Connection strings
For .NET apps, these connection strings are injected into your .NET configuration connectionStrings settings at runtime, overriding existing entries where the key equals the linked database name.
Web 应用程序 → 应用程序设置 → 连接字符串 → 添加连接字符串并将其命名为 db
。
String GetConnectionString()
{
// Get the Connection String from Application Settings (App Service)
// with graceful fallback to web.config
string cs = WebConfigurationManager.ConnectionStrings["db"].ConnectionString;
if (cs == null)
throw new Exception("Could not locate DB connection string");
return cs;
}
What's the difference between the WebConfigurationManager and the ConfigurationManager?
2018 年 5 月更新:
自从 Managed Service Identity 成为现实后,获取访问令牌不再需要将机密(服务主体凭据)存储在您的服务中以访问 Key Vault,这是一个更好的提议。这里有一个 Node.js 示例,只是为了让这个答案更有趣一点:
// Get an access token from Managed Service Identity
// on an Azure IaaS VM
async function getAccessTokenWithMSI() {
let msi = await axios.get('http://169.254.169.254/metadata/identity/oauth2/token',
{
params: {
'api-version': '2018-02-01',
'resource': 'https://vault.azure.net'
},
headers: {
'Metadata': 'true'
},
timeout: 2000
});
return msi.data.access_token;
}
然后:
// Get a secret from Key Vault
async function getSecret(accessToken, secretUrl) {
let response;
try {
response = await axios.get(secretUrl,
{
params: { 'api-version': '2016-10-01' },
headers: { 'Authorization': `Bearer ${accessToken}` },
timeout: 3000
});
}
catch (e) {
console.log('\nError calling Key Vault:,
e.response.status, e.response.statusText, e.response.data);
}
console.log('\nGet Secret response from Key Vault: ',
JSON.stringify(response.data, null, 4));
return response.data;
}
对于 .net Core 并且已经有 Azure Key Vault。现在它非常容易。假设您的连接字符串在 appsettings.json:
{
"ConnectionStrings": {
"MyDatabase": "server=127.0.0.1;port=5678;database=mydb;user=FullMontyBurns;password=hunter2"
}
}
然后您在 Startup.cs
中进行设置:
string connectionString = configuration.GetConnectionString("MyDatabase");
在 Azure Key Vault 中,创建一个机密:
- 姓名:
ConnectionStrings--MyDatabase
- 值:
server=127.0.0.1;port=5678;database=mydb;user=FullMontyBurns;password=hunter2
IConfiguration.GetConnectionString("MyDatabase")
现在从 Key Vault 中获取值。
其他人已经提供了关于如何与 Web 应用程序或 Azure 函数集成的上下文的很好的答案,但这里是开始使用 Key Vault 机密 SDK 的权威参考。
假设的网站当前使用以下方式连接:
public SqlConnection CreateConnection()
{
DbConnection connection = new SqlConnection();
connection.ConnectionString = GetConnectionString();
connection.Open();
return connection;
}
神奇的连接字符串存储在web.config
:
String GetConnectionString()
{
//Get the connection string info from web.config
ConnectionStringSettings cs = ConfigurationManager.ConnectionStrings["db"];
if (cs == null)
throw new Exception("Could not locate DB connection string");
return cs.ConnectionString;
}
现在我想将连接字符串从 web.config 文件移到 Azure KeyVault 中。您如何从 Azure 密钥保管库中检索任何内容?
String GetConnectionString()
{
//Get the connection string info from Azure KeyVault
String connectionString = GetAzureSecret("dbConnectionString");
if (String.IsNullOrWhitespace(connectionString)
throw new Exception.Create("Could not connection string of Azure Key Vault");
return connectionString;
}
除了我刚刚制作了易于使用的 Azure API。 实际api是什么?
未经测试的尝试
string GetAzureSecret(string key)
{
KeyVaultClient vault = new KeyVaultClient();
vault.OnAuthenticate += VaultClientAuthenticate;
var sec = await vault.GetSecretAsync(Key);
return sec.Value;
}
public static async Task<string> VaultClientAuthenticate(string authority, string resource, string scope)
{
String clientID = "8675209";
String clientSecret = "correct battery horse pencil";
var authContext = new AuthenticationContext(authority);
ClientCredential clientCred = new ClientCredential(clientID, clientSecret);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);
if (result == null)
throw new Exception("Could not acquire token");
return result.AccessToken;
}
红利阅读
- MSDN Forums: Storing sql connection string passwords in Key Vault for my Cloud Services
- Easily switching ConnectionStrings on publish to Azure
What is the actual api?
我们可以使用 GetSecret API 来获取值。
准备:
Registry Azure Active Directory application and assign Role
步骤:
1.Create KeyVault 并从 Azure 门户添加机密
2.Config 访问策略
3.Get 访问令牌
var context = new AuthenticationContext("https://login.windows.net/" + tenantId);
ClientCredential clientCredential = new ClientCredential(appId, secretKey);
var tokenResponse =await context.AcquireTokenAsync("https://vault.azure.net", clientCredential);
var accessToken = tokenResponse.AccessToken;
return accessToken;
注意:Keyvault 的资源是https://vault.azure.net
4.Test 使用 Fiddler
我们也可以使用 SDK 轻松做到这一点:
1.Create 一个控制台项目和一个 Utils.cs 文件
public static string EncryptSecret { get; set; }
static string appId = "Application ID";
static string secretKey = "Secert key";
static string tenantId = "TenantId";
public static async Task<string> GetAccessToken(string azureTenantId,string azureAppId,string azureSecretKey)
{
var context = new AuthenticationContext("https://login.windows.net/" + tenantId);
ClientCredential clientCredential = new ClientCredential(appId, secretKey);
var tokenResponse =await context.AcquireTokenAsync("https://vault.azure.net", clientCredential);
var accessToken = tokenResponse.AccessToken;
return accessToken;
}
2.Add 跟随主函数中的代码进行测试。
packages.config 文件
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Hyak.Common" version="1.0.2" targetFramework="net452" />
<package id="Microsoft.Azure.Common" version="2.0.4" targetFramework="net452" />
<package id="Microsoft.Azure.Common.Dependencies" version="1.0.0" targetFramework="net452" />
<package id="Microsoft.Azure.KeyVault" version="1.0.0" targetFramework="net452" />
<package id="Microsoft.Bcl" version="1.1.9" targetFramework="net452" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net452" />
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net452" />
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.13.9" targetFramework="net452" />
<package id="Microsoft.Net.Http" version="2.2.22" targetFramework="net452" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" />
</packages>
我们还可以从 document.
提到的 CtrlDot 获取更多信息2020 年 8 月更新
现在可以通过 Key Vault 引用以零自定义代码从 App Service 调用 Key Vault,这是一种低调的方式。 https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references
从 Key Vault 填充值的应用程序设置示例:
@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931)
如果您不想要版本标识符:
@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)
您需要先在您的应用服务实例和 Key Vault 之间设置托管标识才能使用 Key Vault 引用。
我不反对 Key Vault(我认为它是一个很棒的产品!),但我情不自禁地认为你过度设计了它。
我会简单地使用内置 Application Settings functionality in Azure App Service:
Connection strings
For .NET apps, these connection strings are injected into your .NET configuration connectionStrings settings at runtime, overriding existing entries where the key equals the linked database name.
Web 应用程序 → 应用程序设置 → 连接字符串 → 添加连接字符串并将其命名为 db
。
String GetConnectionString()
{
// Get the Connection String from Application Settings (App Service)
// with graceful fallback to web.config
string cs = WebConfigurationManager.ConnectionStrings["db"].ConnectionString;
if (cs == null)
throw new Exception("Could not locate DB connection string");
return cs;
}
What's the difference between the WebConfigurationManager and the ConfigurationManager?
2018 年 5 月更新:
自从 Managed Service Identity 成为现实后,获取访问令牌不再需要将机密(服务主体凭据)存储在您的服务中以访问 Key Vault,这是一个更好的提议。这里有一个 Node.js 示例,只是为了让这个答案更有趣一点:
// Get an access token from Managed Service Identity
// on an Azure IaaS VM
async function getAccessTokenWithMSI() {
let msi = await axios.get('http://169.254.169.254/metadata/identity/oauth2/token',
{
params: {
'api-version': '2018-02-01',
'resource': 'https://vault.azure.net'
},
headers: {
'Metadata': 'true'
},
timeout: 2000
});
return msi.data.access_token;
}
然后:
// Get a secret from Key Vault
async function getSecret(accessToken, secretUrl) {
let response;
try {
response = await axios.get(secretUrl,
{
params: { 'api-version': '2016-10-01' },
headers: { 'Authorization': `Bearer ${accessToken}` },
timeout: 3000
});
}
catch (e) {
console.log('\nError calling Key Vault:,
e.response.status, e.response.statusText, e.response.data);
}
console.log('\nGet Secret response from Key Vault: ',
JSON.stringify(response.data, null, 4));
return response.data;
}
对于 .net Core 并且已经有 Azure Key Vault。现在它非常容易。假设您的连接字符串在 appsettings.json:
{
"ConnectionStrings": {
"MyDatabase": "server=127.0.0.1;port=5678;database=mydb;user=FullMontyBurns;password=hunter2"
}
}
然后您在 Startup.cs
中进行设置:
string connectionString = configuration.GetConnectionString("MyDatabase");
在 Azure Key Vault 中,创建一个机密:
- 姓名:
ConnectionStrings--MyDatabase
- 值:
server=127.0.0.1;port=5678;database=mydb;user=FullMontyBurns;password=hunter2
IConfiguration.GetConnectionString("MyDatabase")
现在从 Key Vault 中获取值。
其他人已经提供了关于如何与 Web 应用程序或 Azure 函数集成的上下文的很好的答案,但这里是开始使用 Key Vault 机密 SDK 的权威参考。