首页 文章

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

提问于
浏览
6

我无法从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:at Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenNonInteractiveHandler.d__4.MoveNext()在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(工作任务)在Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenHandlerBase.d__57.MoveNext()在System.Runtime.ExceptionServices.ExceptionDispatchInfo .Throw()位于System.Runtime的System.RuntimeModel.Clients.ActiveDirectory.AuthenticationContext.d__37.MoveNext()中的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务).MoveNext()处于System.Runtime的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() Microsoft.Identi的.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) System.Runtime.CompilerServices.TaskAwaiter1.GetResult上的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处的tyModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions.d__0.MoveNext() )在NextDoorScanner.ScannerJob . <GetAccessTokenAsync> d__21.MoveNext()在C:\ Programming \ CommunityScanner \ CommunityScanner \ ScannerJob.cs:第197行的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()在System.Runtime.CompilerServices.TaskAwaiter位于System.Runtime的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()的System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult()处于System.Runtime.KeyVault.KeyVaultCredential.d__9.MoveNext()处的.HandleNonSuccessAndDebuggerNotification(任务任务) System.Runtime.CompilerServices.ConfiguredTaskAwait中的.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()上的Microsoft.Azure.KeyVault.KeyVaultCredential . <ProcessHttpRequestAsync> d__10.MoveNext()处理了.CofiguredTaskAwaiter.GetResult()在System.Runtime.CompilerServices上的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处的Microsoft.Azure.KeyVault.KeyVaultClient . <GetSecretWithHttpMessagesAsync> d__65.MoveNext()处 . 在系统的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处的Microsoft.Azure.KeyVault.KeyVaultClientExtensions.d__11.MoveNext()中配置了TaskAwaitable1.ConfiguredTaskAwaiter.GetResult() . NextDoorScanner.ScannerJob上的Runtime.CompilerServices.TaskAwaiter1.GetResult() . <GetCommunityKeyAsync> d__20.MoveN C:\ Programming \ CommunityScanner \ CommunityScanner \ ScannerJob.cs中的ext():位于System.Runtime的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()的第188行 . CompilerServices.TaskAwaiter1.GetResult()位于C:\ Programming \ CommunityScanner \ CommunityScanner \ NextDoorScannerJob.cs中的NextDoorScanner.NextDoorScannerJob.d__4.MoveNext():位于System.Runtime的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()的第46行 . System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()中的CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)位于C:\ Programming \ CommunityScanner \ CommunityScanner \ Program.cs中的NextDoorScanner.Program.Main(String [] args):行22

我做了一些配置,我想通过powershell将我的桌面注册为Azure用户:

登录 - AzureRmAccount
//我记得,下一行抱怨已经定义了应用ID
New-AzureRmADServicePrincipal -ApplicationId'id-of-app-previous-defined-via-azure-portal'
Set-AzureRmKeyVaultAccessPolicy -VaultName'vault-name'-ServicePrincipalName id-of-app-previous-defined-via-azure-portal -PermissionsToSecrets Get

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

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

3 回答

  • 9

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

    步骤摘要:

    • 注册应用

    • 在这个新注册的App中创建Key

    • 创建密钥保管库并为应用分配权限

    • 在保险库内创建秘密

    通过代码访问它们

    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:

    How to register your app in Azure

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

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

    How to create Azure Key Vault and Assign Permissions

    How to create Azure Key Vault and Assign Permissions

    How to create Azure secrets

    How to create Azure secrets

    How to access it thru code

    enter image description here

  • 4

    除了Tom提供的内容之外,在我最终想出如何让事情发挥作用后,我记录了我在https://jumpforjoysoftware.com/2017/12/azure-key-vaults/学到的东西 . 希望这将为人们带来一些严重的挫败感 .

  • 2

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

    在我们注册Azure目录应用程序之后,我们需要assign role to application . 如果我们想要运行Azure Key Vault,我们还需要授予操作Key Vault的权限 . 密钥保管库的资源是 https://vault.azure.net . 您还可以从另一个SO thread获取更多详细信息 .

    演示代码:

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

相关问题