无法从桌面控制台应用访问Azure Key Vault

Mar*_*ert 9 c# azure azure-active-directory azure-keyvault

我无法从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;
    }
Run Code Online (Sandbox Code Playgroud)

以下是抛出的异常:

Microsoft.IdentityModel.Clients.ActiveDirectory.AdalException
HResult = 0x80131500 Message = unknown_user:无法识别登录用户Source = Microsoft.IdentityModel.Clients.ActiveDirectory
StackTrace:at Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenNonInteractiveHandler.d__4.MoveNext()at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(工作任务)在Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenHandlerBase.d__57.MoveNext()在System.Runtime.ExceptionServices.ExceptionDispatchInfo.
在System.Runtime的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()上的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中的System.RdentityModel.Clients.ActiveDirectory.AuthenticationContext.d__37.MoveNext()
处抛出(). Microsoft.Identity的CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)在System.Runtime.CompilerServices.TaskAwaiter的
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()中的Model.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions.d__0.MoveNext()1.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.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter .GetResult()在System.Runtime.CompilerServices
上的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()上的Microsoft.Azure.KeyVault.KeyVaultCredential.d__9.MoveNext().ConfiguredTaskAwaitable 1.ConfiguredTaskAwaiter.GetResult()在Microsoft.Azure.KeyVault.KeyVaultClientExtensions.d__11.MoveNext()在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(工作任务)在System.Runtime.CompilerServices.TaskAwaiter 1.GetResult()在NextDoorScanner.NextDoorScannerJob.d__4.M C:\ Programming\CommunityScanner\CommunityScanner\NextDoorScannerJob.cs中的oveNext():位于System.Runtime的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()的第46行. CompilerServices.TaskAwaiter`1.GetResult()位于C:\ Programming\CommunityScanner\CommunityScanner\Program.cs中的NextDoorScanner.Program.Main(String [] args):第22行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.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

我做了一些配置,我想通过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
Run Code Online (Sandbox Code Playgroud)

我不清楚我是否应该向GetSecretAsync()提供保险库密钥.我也想知道我是否应该做一些事情而不是将新创建的UserCredential传递给AcquireTokenAsync().最后,我在网上看到了创建存储帐户以供密钥保险库使用的参考资料,但我没有创建我在"存储帐户"中使用的保险库.而且我没有在代码中识别存储帐户.

帮助或参考从控制台桌面应用程序访问密钥保险库的非常好的示例将不胜感激.

ndd*_*ndd 15

Mark的博客非常有用,我从博客那里学会了如何去做,以下是截至2018年11月6日的步骤和代码.

步骤摘要:

  1. 注册应用程序
  2. 在这个新注册的App中创建Key
  3. 创建密钥保管库并为应用分配权限
  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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何注册您的应用程序:

如何在Azure中注册您的应用程序

如何创建Azure应用程序的密码并获取应用程序的ID

如何创建应用程序的密码并获取应用程序的ID

如何创建Azure密钥保管库和分配权限

如何创建Azure密钥保管库和分配权限

如何创建Azure机密

如何创建Azure机密

如何通过代码访问它

在此输入图像描述

  • 我不明白“ClientId 和 Secret”方法。好的,我不会在配置文件中公开我的实际秘密(例如服务密码),但我会在配置文件中公开一个 ClientId 和一个 Secret,每个人都可以看到它们,然后使用它们来访问密钥保管库,然后找回我真正的秘密。所以,我只是将问题进一步推进,而不是解决它,对吗? (4认同)

Mar*_*ert 8

除了汤姆提供的东西之外,在我终于弄清楚如何使事情正常工作之后,我在https://jumpforjoysoftware.com/2017/12/azure-key-vaults/上记录了我学到的东西。希望这将使人们免于严重的挫败感。