无法从桌面控制台应用

时间:2017-12-18 20:01:39

标签: 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;
    }

以下是抛出的异常:

  

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.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.d__37.MoveNext()   在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  在   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions.d__0.MoveNext()   在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  在   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   System.Runtime.CompilerServices.TaskAwaiter 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.ConfiguredTaskAwaitable 1.ConfiguredTaskAwaiter.GetResult()   在   Microsoft.Azure.KeyVault.KeyVaultCredential.d__9.MoveNext()   在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  在   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)   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()   在   Microsoft.Azure.KeyVault.KeyVaultClientExtensions.d__11.MoveNext()   在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  在   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)在System.Runtime.CompilerServices.TaskAwaiter 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 1.GetResult()   在NextDoorScanner.NextDoorScannerJob.d__4.MoveNext()中   C:\程序\ CommunityScanner \ CommunityScanner \ NextDoorScannerJob.cs:行   46点   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务   任务)在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()   在NextDoorScanner.Program.Main(String [] args)中   C:\ Programming \ CommunityScanner \ CommunityScanner \ Program.cs:第22行

我做了一些配置,我想通过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()。最后,我在网上看到了创建存储帐户以供密钥保险库使用的参考资料,但我没有创建我在“存储帐户”中使用的保险库。而且我没有在代码中识别存储帐户。

帮助,或者对从控制台桌面应用程序访问密钥保管库的非常好的示例的引用将不胜感激。

4 个答案:

答案 0 :(得分:11)

Mark的博客非常有帮助,我从该博客中学到了如何做,以下是截至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密钥保管库和分配权限

How to create Azure Key Vault and Assign Permissions

如何创建Azure机密

How to create Azure secrets

如何通过代码访问它

enter image description here

答案 1 :(得分:6)

除了汤姆提供的内容之外,在我最终想出如何让事情发挥作用之后,我记录了我在https://jumpforjoysoftware.com/2017/12/azure-key-vaults/学到的东西。希望这一切都会让人们感到非常沮丧。

答案 2 :(得分: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;
  }

答案 3 :(得分:0)

Here are the docs and samples,了解如何使用最新版本的Azure SDK(Azure.Security.KeyVault.Secrets)。

以防万一,以下是一些其他受支持语言的相同文档:

Java

JavaScript

Python