J'ai du mal à accéder à un secret à partir d'un coffre de clés Azure. Je soupçonne que le problème est que je ne comprends pas bien la terminologie, donc les arguments que je fournis aux différents appels d'API sont faux.
Voici le code de base que j'utilise:
protected async Task<string> GetCommunityKeyAsync( UserConfiguration user )
{
var client = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback( GetAccessTokenAsync ),
new HttpClient() );
// user.VaultUrl is the address of my key vault
// e.g., https://previously-created-vault.vault.Azure.net
var secret = await client.GetSecretAsync( user.VaultUrl, "key-to-vault-created-in-Azure-portal" );
return secret.Value;
}
private async Task<string> GetAccessTokenAsync( string authority, string resource, string scope )
{
var context = new AuthenticationContext( authority, TokenCache.DefaultShared );
// this line throws a "cannot identify user exception; see
// below for details
var result =
await context.AcquireTokenAsync( resource, "id-of-app-registered-via-Azure-portal", new UserCredential() );
return result.AccessToken;
}
Voici l'exception qui est levée:
Microsoft.IdentityModel.Clients.ActiveDirectory.AdalException
HResult = 0x80131500 Message = unknown_user: impossible d'identifier l'utilisateur connecté Source = Microsoft.IdentityModel.Clients.ActiveDirectory
StackTrace: sur Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenNonInteractiveHandler.d__4.MoveNext () sur System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
sur System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) sur Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenHandlerBase.d__57.MoveNext () sur System.Runtime.ExceptionException
sur System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) sur Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.d__37.MoveNext () sur System.Runtime.ExceptionServices.Ex)
sur System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) sur Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions.d__0.MoveNext () sur System.RuntimeExExceptionInserve.Ex0
sur System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) sur System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at NextDoorScanner.ScannerJob.<GetAccessTokenAsync>d__21.MoveNext() in C:\Programming\CommunityScanner\CommunityScanner\ScannerJob.cs:line 197 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable
1.ConfiguredTaskAwaiter.GetResult () sur Microsoft.Azault.VaultKey MoveNext () à System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
sur System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) sur System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at Microsoft.Azure.KeyVault.KeyVaultCredential.<ProcessHttpRequestAsync>d__10.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
1.ConfiguredTaskAwaiter.GetResult (V) .Cl Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.KeyVault.KeyVaultClient.<GetSecretWithHttpMessagesAsync>d__65.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable
sur System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) sur System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at NextDoorScanner.ScannerJob.<GetCommunityKeyAsync>d__20.MoveNext() in C:\Programming\CommunityScanner\CommunityScanner\ScannerJob.cs:line 188 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult () sur NextDoorScanner.NextDoorScannerJon.dInScanner.NextDoorScanner:\Programming\CommunityScanner\CommunityScanner\NextDoorScannerJob.cs: ligne 46 sur System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () sur System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task task) sur System.Reservice.Compiler GetResult () à NextDoorScanner.Program.Main (String [] args) dans C:\Programming\CommunityScanner\CommunityScanner\Program.cs: ligne 22
J'ai fait une configuration, je pensais impliquer l'enregistrement de mon bureau en tant qu'utilisateur Azure, via powershell:
Login-AzureRmAccount // as I recall, this next line complained about the app ID already being defined New-AzureRmADServicePrincipal -ApplicationId 'id-of-app-previously-defined-via-Azure-portal' Set-AzureRmKeyVaultAccessPolicy -VaultName 'vault-name' -ServicePrincipalName id-of-app-previously-defined-via-Azure-portal -PermissionsToSecrets Get
Je ne sais pas si je suis censé fournir la clé du coffre-fort à GetSecretAsync (). Je me demande également si je suis censé faire autre chose que de passer un UserCredential nouvellement créé à AcquireTokenAsync (). Enfin, je vois des références en ligne à la création d'un compte de stockage à utiliser avec des coffres-clés, ce que j'ai fait, mais je n'ai pas créé le coffre-fort que j'utilise "dans" un compte de stockage. Et je n'identifie pas le compte de stockage dans le code.
De l'aide ou une référence à un très bon exemple d'accès aux coffres-forts depuis une application de bureau de console serait appréciée.
Le blog de Mark a été extrêmement utile, à partir de ce blog, j'ai appris à le faire et voici les étapes et le code à partir du 6 novembre 2018.
Résumé des étapes:
Accédez-y via le code
using Microsoft.Azure.KeyVault;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace Experiments.AzureKeyValut
{
internal class AzureKeyValueDemo
{
private static async Task Main(string[] args)
{
await GetSecretAsync("https://YOURVAULTNAME.vault.Azure.net/", "YourSecretKey");
}
private static async Task<string> GetSecretAsync(string vaultUrl, string vaultKey)
{
var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessTokenAsync), new HttpClient());
var secret = await client.GetSecretAsync(vaultUrl, vaultKey);
return secret.Value;
}
private static async Task<string> GetAccessTokenAsync(string authority, string resource, string scope)
{
//DEMO ONLY
//Storing ApplicationId and Key in code is bad idea :)
var appCredentials = new ClientCredential("YourApplicationId", "YourApplicationKey");
var context = new AuthenticationContext(authority, TokenCache.DefaultShared);
var result = await context.AcquireTokenAsync(resource, appCredentials);
return result.AccessToken;
}
}
}
Comment enregistrer votre application:
Comment créer le mot de passe de l'application Azure et obtenir l'ID de votre application
Comment créer Azure Key Vault et attribuer des autorisations
Comment créer des secrets Azure
Comment y accéder via le code
En plus de ce que Tom a fourni, après avoir finalement compris comment faire fonctionner les choses, j'ai documenté ce que j'ai appris sur https://jumpforjoysoftware.com/2017/12/Azure-key-vaults/ . Espérons que cela sauvera les gens de graves frustrations.
De l'aide, ou une référence à un très bon exemple d'accès aux coffres-forts depuis une application de bureau de console serait appréciée.
Après avoir enregistré l'application Azure Directory, nous devons attribuer un rôle à l'application . si nous voulons faire fonctionner Azure Key Vault, nous devons également autoriser le fonctionnement de Key Vault. La ressource pour le coffre de clés est https://vault.Azure.net
. Vous pouvez également obtenir des informations plus détaillées d'un autre filetage SO .
Code de démonstration:
static string appId = "application Id";
static string tenantId = "tenant id";
static string uri = "http://localhost:13526"; //redirect uri
static void Main(string[] args)
{
var kv = new KeyVaultClient(GetAccessToken);
var scret = kv.GetSecretAsync("https://xxxx.vault.Azure.net", "xxxx").GetAwaiter().GetResult();
}
public static async Task<string> GetAccessToken(string azureTenantId,string clientId,string redirectUri)
{
var context = new AuthenticationContext("https://login.windows.net/" + tenantId);
var tokenResult = await context.AcquireTokenAsync("https://vault.Azure.net", appId, new Uri(uri), new PlatformParameters(PromptBehavior.SelectAccount));
return tokenResult.AccessToken;
}