web-dev-qa-db-ja.com

デスクトップコンソールアプリからAzure Key Vaultにアクセスできない

Azureキーコンテナーからシークレットにアクセスできません。問題は、用語を十分に理解していないためだと思います。そのため、さまざまなAPI呼び出しに提供している引数は間違っています。

これが私が使っている基本的なコードです:

_    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;
    }
_

スローされる例外は次のとおりです。

Microsoft.IdentityModel.Clients.ActiveDirectory.AdalException
HResult = 0x80131500 Message = unknown_user:ログインしたユーザーを識別できませんでしたSource = Microsoft.IdentityModel.Clients.ActiveDirectory
StackTrace:Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenNonInteractiveHandler.d__4.MoveNext()at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenHandlerBase.d__57.MoveNext()at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.d__37.MoveNext()at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions.d__0.MoveNext()at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()のSystem.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)で
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at 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()at Microsoft.Azure.KeyVault.KeyVaultCredential.d__9。 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()のMoveNext()
System.Runtime.CompilerServices.ConfiguredTaskAwaitable _1.ConfiguredTaskAwaiter.GetResult() at Microsoft.Azure.KeyVault.KeyVaultCredential.<ProcessHttpRequestAsync>d__10.MoveNext() at System.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
_ 1.ConfiguredTaskAwaiter.GetResult()at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at Microsoft.Azure.KeyVault.KeyVaultClientExtensions.d_ )System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()で
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at 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()at NextDoorScanner.NextDoorScannerJob.d__4.MoveNext()in C:\Programming\CommunityScanner\CommunityScanner\NextDoorScannerJob.cs:line 46 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at System.Runtime.CompilerServices.TaskAwaiter` C:\ Programming\CommunityScanner\CommunityScanner\Program.cs:line 22のNextDoorScanner.Program.Main(String [] args)にあるGetResult()

いくつかの構成を行いましたが、Powershellを介してデスクトップをAzureユーザーとして登録する必要があると思いました。

_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
_

GetSecretAsync()にボールトキーを提供することになっているかどうかは不明です。また、新しく作成したUserCredentialをAcquireTokenAsync()に渡す以外のことをしているのだろうか。最後に、キーコンテナーで使用するストレージアカウントの作成についてオンラインで参照していますが、ストレージアカウントの「in」で使用しているコンテナーは作成していません。また、コードでストレージアカウントを特定していません。

ヘルプ、またはコンソールデスクトップアプリからキーコンテナーにアクセスする本当に良い例への参照をいただければ幸いです。

10
Mark Olbert

マークのブログは非常に役に立ちました。そのブログから私はそれを行う方法を学びました。以下は、2018年11月6日のステップとコードです。

手順の概要:

  1. アプリを登録
  2. この新しく登録されたアプリ内にキーを作成します
  3. Key Vaultを作成し、アプリに権限を割り当てます
  4. ボールト内にシークレットを作成する

コードを介してそれらにアクセスする

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;
        }
    }
}

アプリの登録方法:

How to register your app in Azure

Azureアプリのパスワードを作成してアプリのIDを取得する方法

How to create your App's password and get your App's Id

Azure Key Vaultを作成してアクセス許可を割り当てる方法

How to create Azure Key Vault and Assign Permissions

Azureシークレットの作成方法

How to create Azure secrets

コードを介してそれにアクセスする方法

enter image description here

20
ndd

トムが提供したものに加えて、物事を機能させる方法を最終的に理解した後、私は私が学んだことを文書化しました https://jumpforjoysoftware.com/2017/12/Azure-key-vaults/ 。うまくいけば、これはすべての人々にいくつかの深刻な欲求不満を救うでしょう。

8
Mark Olbert

ヘルプ、またはコンソールデスクトップアプリからキーコンテナーにアクセスする本当に良い例への参照をいただければ幸いです。

Azure Directoryアプリを登録した後、 アプリケーションにロールを割り当てる を行う必要があります。 Azure Key Vaultを操作する場合は、Key Vaultを操作する権限も付与する必要があります。 Key Vaultのリソースはhttps://vault.Azure.net。また、別の SOスレッド から詳細情報を取得することもできます。

デモコード:

 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;
  }
2
Tom Sun - MSFT