9

I am attempting to put some output from a service I am running in a Key Vault in Azure. The output of my service will be user credentials which is why I want to use Key Vault for this purpose.

So far, I have tried the KeyVaultClient's SetSecretAsync method, but it's not working for me, I am not getting any error messages however I'm also not seeing a new secret created in my targetted KeyVault. I have not been able to find a KeyVaultClient Add Secret method as it does not exist, am I using the right object/method here?

The method in question here is AddResult.

Here is my code:

 private static AzureKeyVault instance; private static KeyVaultClient client; private AzureKeyVault() { //initialize the azure key vault var vaultAddress = ConfigurationManager.AppSettings["VaultUri"]; client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken)); } public static async Task<string> GetAccessToken(string authority, string resource, string scope) { var clientId = ConfigurationManager.AppSettings["ClientID"]; var clientSecret = ConfigurationManager.AppSettings["ClientSecret"]; ClientCredential clientCredential = new ClientCredential(clientId, clientSecret); var context = new AuthenticationContext(authority, TokenCache.DefaultShared); var result = await context.AcquireTokenAsync(resource, clientCredential); return result.AccessToken; } public static AzureKeyVault GetInstance { get { if (instance == null) { instance = new AzureKeyVault(); } return instance; } } public void AddResult(string machineIPAndPort, BruteForceResult result) { client.SetSecretAsync("https://vaultURI(redacted).vault.azure.net/", machineIPAndPort, JsonConvert.SerializeObject(result)); } 
5
  • What does it's not working for me mean? Commented Oct 18, 2017 at 18:54
  • 1
    Goal == Title (Add Secret to Key Vault) Result == No secret added and no error messages. Commented Oct 18, 2017 at 19:01
  • In the Secret, the machineIPandPort would be the name, and the serialized result would be the Value. Commented Oct 18, 2017 at 19:03
  • Shouldn't you await that SetSecretAsync call (or .Result if you're in a real hurry)? Works just fine for me. Commented Oct 18, 2017 at 19:10
  • How would I do that? just save the output of the SetSecretAsync to a variable and await it? like var res = await client.SetSecretAsync then change my return type on AddResult? Commented Oct 18, 2017 at 19:12

1 Answer 1

11

Use patience (await creation).

// Let's create a secret and read it back string vaultBaseUrl = "https://alice.vault.azure.net"; string secret = "from-NET-SDK"; // Await SetSecretAsync KeyVaultClient keyclient = new KeyVaultClient(GetToken); var result = keyclient.SetSecretAsync(vaultBaseUrl, secret, "Sup3eS3c5et").Result; // Print indented JSON response string prettyResult = JsonConvert.SerializeObject(result, Formatting.Indented); Console.WriteLine($"SetSecretAsync completed: {prettyResult}\n"); // Read back secret string secretUrl = $"{vaultBaseUrl}/secrets/{secret}"; var secretWeJustWroteTo = keyclient.GetSecretAsync(secretUrl).Result; Console.WriteLine($"secret: {secretWeJustWroteTo.Id} = {secretWeJustWroteTo.Value}"); 

Result:

SetSecretAsync completed: { "SecretIdentifier":{ "BaseIdentifier":"https://alice.vault.azure.net:443/secrets/from-NET-SDK", "Identifier":"https://alice.vault.azure.net:443/secrets/from-NET-SDK/59793...", "Name":"from-NET-SDK", "Vault":"https://alice.vault.azure.net:443", "VaultWithoutScheme":"alice.vault.azure.net", "Version":"597930b70565447d8ba9ba525a206a9e" }, "value":"Sup3eS3c5et", "id":"https://alice.vault.azure.net/secrets/from-NET-SDK/59...", "contentType":null, "attributes":{ "recoveryLevel":"Purgeable", "enabled":true, "nbf":null, "exp":null, "created":1508354384, "updated":1508354384 }, "tags":null, "kid":null, "managed":null } secret: https://alice.vault.azure.net/secrets/from-NET-SDK/59793... = Sup3eS3c5et 

What you should really do is rewrite AddResult():

public bool AddResult(string machineIPAndPort, BruteForceResult result) { await result = client.SetSecretAsync("https://vaultURI(redacted).vault.azure.net/", machineIPAndPort, JsonConvert.SerializeObject(result)); return true; } 

And maybe wrap that in a try-catch and read the InnerException since that's where the meaningful HTTP response body will be. For example, making the request against a Key Vault i don't have access to results in:

InnerException

And also because this is the cloud, you're in for fierce competition with other mission critical traffic, things will fail.

Sign up to request clarification or add additional context in comments.

4 Comments

This worked wonderfully, thank you. I guess the issue was that I had to await the result... something you'd think they would document. Thank you EvilSnobu
You actually taught me a lot about how async works and little kluges on getting the results instead of implimenting async... Thank you sir!
But you should not do that, you should implement proper async/await. But you know.. life's short :)
haha I figured it is kinda of a kluge,,, but I appreciate the quick win =) thanks again.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.