Un site Web hypothétique se connecte actuellement en utilisant:
public SqlConnection CreateConnection()
{
DbConnection connection = new SqlConnection();
connection.ConnectionString = GetConnectionString();
connection.Open();
return connection;
}
Où la chaîne de connexion magique est stockée dans 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;
}
Maintenant, je voudrais déplacer la chaîne de connexion du fichier web.config vers Azure KeyVault. Comment récupérer quoi que ce soit hors du coffre de clés 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;
}
Sauf que je viens de créer l'API Azure facile à utiliser. Quelle est api réelle ?
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;
}
Quelle est l'api réelle?
Nous pourrions utiliser GetSecret API pour obtenir de la valeur.
Préparation:
Enregistrer l'application Azure Active Directory et attribuer un rôle
Étapes:
1.Créez KeyVault et ajoutez un secret à partir du portail Azure
2. Politique d'accès à la configuration
3.Obtenir un jeton d'accès
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;
Remarque : La ressource pour Keyvault est https://vault.Azure.net
4.Tester avec Fiddler
Nous pouvons également le faire facilement avec le SDK:
1.Créez un projet de console et un fichier 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.Ajoutez le code suivant dans la fonction principale et testez-le.
fichier 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>
Nous pouvons également obtenir plus d'informations de CtrlDot mentionné document .
Je n'ai rien contre Key Vault (je pense que c'est un excellent produit!), Mais je ne peux pas m'en empêcher, mais je pense que vous êtes en train de trop l'ingénierie.
J'utiliserais simplement la fonctionnalité intégrée Paramètres d'application dans Azure App Service :
Chaînes de connexion
Pour les applications .NET, ces chaînes de connexion sont injectées dans vos paramètres connectionStrings de configuration .NET lors de l'exécution, remplaçant les entrées existantes où la clé est égale au nom de la base de données liée.
Application Web → Paramètres d'application → Chaînes de connexion → Ajouter une chaîne de connexion et nommez-la 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;
}
Quelle est la différence entre WebConfigurationManager et ConfigurationManager?
Depuis Managed Service Identity est devenu une chose, l'acquisition d'un jeton d'accès ne nécessite plus de secrets (informations d'identification de principal de service) stockés dans votre service pour accéder à Key Vault, ce qui est une bien meilleure proposition. Voici un exemple Node.js juste pour pimenter un peu cette réponse:
// 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;
}
et alors:
// 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;
}