Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Adal for accessing the Azure KeyVault on behalf of a user

The following is in a console application and ClientID, RedirectUri is from the created native app in azure active directory.

var authContext = new AuthenticationContext(string.Format("https://login.windows.net/{0}","common"),new FileCache());
var token = authContext.AcquireToken("https://management.core.windows.net/", ClientID, RedirectUri, PromptBehavior.Auto);

I now have the token for talking with management api.

 using (var client = new KeyVaultManagementClient(new TokenCloudCredentials(SubscriptionId, token.AccessToken)))
 {
     var a = client.Vaults.List(resourceGroup, 10);
     foreach(var vault in a.Vaults)
     {
           var vaultInfo = client.Vaults.Get(resourceGroup, vault.Name);
           Console.WriteLine(JsonConvert.SerializeObject(vaultInfo.Vault, Formatting.Indented));
           //Verifying that the AccessPolicies contains my object id (pasting idtoken into jwt.io and compare with oid claim) Success.

           // Now its time to talk with keyvault
           var keyvault = new KeyVaultClient(GetAccessTokenAsync);
           var secrets = keyvault.GetSecretsAsync(vaultInfo.Vault.Properties.VaultUri).GetAwaiter().GetResult();

     }

 }


 private static Task<string> GetAccessTokenAsync(string authority, string resource, string scope)
 {
         var context = new AuthenticationContext(authority, new FileCache());
        var result = context.AcquireToken(resource, new ClientCredential(AppClientId,AppKey));

        return Task.FromResult(result.AccessToken);

 }

Above works but require me to create a separate app on my AD that can talk with the keyvault. I would like to use my own ID to talk with keyvault, but I cant figure out how to get the access token that the keyvault client require.

Do i need to update the manifest on azure manuel and adding that my console app is allowed to get a token on behalf of users to keyvault? What code is needed to be changed in GetAccessTokenAsync to make it work.

I have tried giving it just the access or id tokens from the initial token request from the common endpoint. Do anyone have some suggestions on how to talk to azure key vault on behalf of my own id and not an app?

Update

So looking at headers i found out my token was missing vault.azure.net as resource and therefore trying:

var testtoken = authContext.AcquireToken("https://vault.azure.net", ClientID, RedirectUri);

gives the following error:

AADSTS65005: The client application has requested access to resource 'https://vault.azure.net'. This request has failed because the client has not specified this resource in its requiredResourceAccess list.

and looking at the current manifest:

"requiredResourceAccess": [
    {
      "resourceAppId": "797f4846-ba00-4fd7-ba43-dac1f8f63013",
      "resourceAccess": [
        {
          "id": "41094075-9dad-400e-a0bd-54e686782033",
          "type": "Scope"
        }
      ]
    },
    {
      "resourceAppId": "00000002-0000-0000-c000-000000000000",
      "resourceAccess": [
        {
          "id": "311a71cc-e848-46a1-bdf8-97ff7156d8e6",
          "type": "Scope"
        }
      ]
    }
  ],

How do i know what guids to use for scope and resourceAppId for the keyvault?

Temp Solution

Until i know how to get the resourceAppId and related information I am using the old trick of impersonating the powershell tools.

 var vaultToken = authContext.AcquireToken("https://vault.azure.net", "1950a258-227b-4e31-a9cf-717495945fc2", new Uri("urn:ietf:wg:oauth:2.0:oob"));
 var keyvault = new KeyVaultClient((_, b, c) => Task.FromResult(vaultToken.AccessToken));    
 var secrets = keyvault.GetSecretsAsync(vaultInfo.Vault.Properties.VaultUri).GetAwaiter().GetResult();

source: http://www.s-innovations.net/Blog/2014/02/12/Controlling-the-login-flow-when-using-ADAL-for-WAML Please also read @bradygaster comment at the blog post before using the powershells clientid.

like image 207
Poul K. Sørensen Avatar asked May 07 '15 09:05

Poul K. Sørensen


People also ask

How do I access Keyvault certificate?

Create a service principal. Access to Key Vault is granted to either a user or a service principal. To access Key Vault programmatically, use a service principal with the certificate you created in the previous step. The service principal must be in the same Azure AD tenant as the Key Vault.


1 Answers

You're on the right track! You need to configure AAD to be able to authorize users specifically for access to KeyVault. Try adding the following to your manifest.

{
      "resourceAppId": "cfa8b339-82a2-471a-a3c9-0fc0be7a4093",
      "resourceAccess": [
        {
          "id": "f53da476-18e3-4152-8e01-aec403e6edc0",
          "type": "Scope"
        }
      ]
}

If that doesn't work, you can do this the old-fashioned way by visiting the old portal, navigating to AAD, your AAD Tenant, your application, and adding "Azure Key Vault" under the "permissions to other applications" section of the "Configure" tab.

like image 153
bengreenier Avatar answered Oct 16 '22 20:10

bengreenier