Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List secrets in a KeyVault without logging in for every secret?

I've successfully managed to list all of the secrets in an Azure KeyVault - however I need to make a call to get a token each time I want to get the next secret.

How do I store the credentials so I only have to login once during the loop?

    public async Task<List<string>> getsecretslist(string url)
    {

        var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetToken));

        List<string> secretlist = new List<string>(); 
        var all = kv.GetSecretsAsync(url);
        var myId = "";
        foreach (Microsoft.Azure.KeyVault.Models.SecretItem someItem in all.Result)
        {
            myId = someItem.Id;
            var mOtherThing = someItem.Identifier;
            var yep = await kv.GetSecretAsync(mOtherThing.ToString());
            secretlist.Add(yep.Value);
        }

        return secretlist;
    }
like image 248
Pikapops Avatar asked Jan 05 '23 09:01

Pikapops


2 Answers

In your GetToken callback method you need to cache the access token as long as it is valid and not expired. Then your callback will return the cached access token instead of doing the authentication again. The following code snippet will use the ADAL default token cache (e.g. TokenCache.DefaultShared).

public static async Task<string> GetToken(string authority, string resource, string scope)
{
    var assertionCert = new ClientAssertionCertificate(clientId, certificate);
    var context = new AuthenticationContext(authority, TokenCache.DefaultShared);
    var result = await context.AcquireTokenAsync(resource, assertionCert).ConfigureAwait(false);

    return result.AccessToken;
}
like image 177
Pooneh Avatar answered Jan 25 '23 09:01

Pooneh


The best way that i found is to save the token you obtained in your GetToken function, for example:

var authenticationContext = new AuthenticationContext(authority, TokenCache.DefaultShared);

var authenticationResult = await authenticationContext.AcquireTokenAsync(resource, KeyVaultUserClientId, new Uri(KeyVaultRedirectUri), new PlatformParameters(PromptBehavior.SelectAccount)).ConfigureAwait(false);

return authenticationResult.AccessToken;

Then i simply altered the getter for the client so it will check for the expiry, if its still valid (should have expiration of 60 minutes) it will return a simpler client which returns the lastAuthenticationResult

private static KeyVaultClient KeyVaultClient
{
    get
    {
        if (lastAuthenticationResult != null && DateTime.UtcNow.AddSeconds(5) < lastAuthenticationResult.ExpiresOn)
        {
            if (m_cachedKeyVaultClient != null)
            {
                return m_cachedKeyVaultClient;
            }
            else
            {
                return new KeyVaultClient(getCachedToken);
            }
        }

        if (m_keyVaultClient == null)
            m_keyVaultClient = new KeyVaultClient(GetAccessTokenAsync);

        return m_keyVaultClient;
    }
}


private static async Task<string> getCachedToken(string authority, string resource, string scope)
{
    return lastAuthenticationResult.AccessToken;
}
like image 26
Ohad Bitton Avatar answered Jan 25 '23 09:01

Ohad Bitton