1
votes

I have a web API method which creates secrets on azure key vault and it works fine, I also have a delete method that deletes an entity and its associated secrets, however, this method is not deleting the key on azure key vault, but it's not throwing an exception either!

Here the helper methods:

 public async Task OnCreateSecretAsync(string name, string value)
        {
            Message = "Your application description page.";
            int retries = 0;
            bool retry = false;
            try
            {
                /* The below 4 lines of code shows you how to use AppAuthentication library to set secrets from your Key Vault*/
                AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
                KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
                var result = await keyVaultClient.SetSecretAsync(ConfigurationManager.AppSettings["VaultUrl"].ToString(), name, value)
                            .ConfigureAwait(false);
                SecretIdentifier = result.Id;


                /* The below do while logic is to handle throttling errors thrown by Azure Key Vault. It shows how to do exponential backoff which is the recommended client side throttling*/
                do
                {
                    long waitTime = Math.Min(GetWaitTime(retries), 2000000);
                    result = await keyVaultClient.SetSecretAsync(ConfigurationManager.AppSettings["VaultUrl"].ToString(), name, value)
                        .ConfigureAwait(false);
                    Message = result.Id;
                    retry = false;
                }
                while (retry && (retries++ < 10));
            }
            /// <exception cref="KeyVaultErrorException">
            /// Thrown when the operation returned an invalid status code
            /// </exception>
            catch (KeyVaultErrorException keyVaultException)
            {
                Message = keyVaultException.Message;
                if ((int)keyVaultException.Response.StatusCode == 429)
                    retry = true;
            }
        }

        /// <summary>
        /// Deletes secrets
        /// </summary>
        /// <param name="name">Secret</param>
        /// <param name="value">Value</param>
        /// <returns></returns>
        public async Task OnDeleteSecretAsync(string name)
        {
            Message = "Your application description page.";
            int retries = 0;
            bool retry = false;
            try
            {
                /* The below 4 lines of code shows you how to use AppAuthentication library to set secrets from your Key Vault*/
                AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
                KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
                var result = await keyVaultClient.DeleteSecretAsync(ConfigurationManager.AppSettings["VaultUrl"].ToString(), name)
                            .ConfigureAwait(false);
                SecretIdentifier = result.Id;


                /* The below do while logic is to handle throttling errors thrown by Azure Key Vault. It shows how to do exponential backoff which is the recommended client side throttling*/
                do
                {
                    long waitTime = Math.Min(GetWaitTime(retries), 2000000);
                    result = await keyVaultClient.DeleteSecretAsync(ConfigurationManager.AppSettings["VaultUrl"].ToString(), name)
                        .ConfigureAwait(false);
                    Message = result.Id;
                    retry = false;
                }
                while (retry && (retries++ < 10));
            }
            /// <exception cref="KeyVaultErrorException">
            /// Thrown when the operation returned an invalid status code
            /// </exception>
            catch (KeyVaultErrorException keyVaultException)
            {
                Message = keyVaultException.Message;
                if ((int)keyVaultException.Response.StatusCode == 429)
                    retry = true;
            }
        }

And here the methods where I call them from:

 public async Task<IHttpActionResult> AddGlobalDesignTenant([FromBody]GlobalDesignTenant globaldesigntenant)
        {
            var telemetry = new TelemetryClient();
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                string domainUrl = globaldesigntenant.TestSiteCollectionUrl;
                string tenantName = domainUrl.Split('.')[0].Remove(0, 8);
                globaldesigntenant.TenantName = tenantName;

                var globalDesignTenantStore = CosmosStoreHolder.Instance.CosmosStoreGlobalDesignTenant;
                byte[] data = Convert.FromBase64String(globaldesigntenant.base64CertFile);

                var cert = new X509Certificate2(
                    data,
                    globaldesigntenant.CertificatePassword,
                    X509KeyStorageFlags.Exportable |
                    X509KeyStorageFlags.MachineKeySet |
                    X509KeyStorageFlags.PersistKeySet);

                try
                {
                    using (var cc = new AuthenticationManager().GetAzureADAppOnlyAuthenticatedContext(globaldesigntenant.TestSiteCollectionUrl, 
                        globaldesigntenant.Applicationid,
                        globaldesigntenant.TenantName + ".onmicrosoft.com", 
                        cert, AzureEnvironment.Production))
                    {
                        cc.Load(cc.Web, p => p.Title);
                        cc.ExecuteQuery();
                        Console.WriteLine(cc.Web.Title);
                    }

                }
                catch (Exception ex)
                {
                    return BadRequest("Cant authenticate with those credentials");
                }              


                KeyVaultHelper keyVaultHelperPFX = new KeyVaultHelper();
                await keyVaultHelperPFX.OnCreateSecretAsync("GlobalDesignTenantPFXFileBAse64"+ tenantName, globaldesigntenant.base64CertFile);
                globaldesigntenant.SecretIdentifierBase64PFXFile = keyVaultHelperPFX.SecretIdentifier;


                KeyVaultHelper keyVaultHelperPassword = new KeyVaultHelper();
                await keyVaultHelperPassword.OnCreateSecretAsync("GlobalDesignTenantCertPassword" + tenantName, globaldesigntenant.CertificatePassword);
                globaldesigntenant.SecretIdentifieCertificatePassword = keyVaultHelperPassword.SecretIdentifier;

                globaldesigntenant.CertificatePassword = string.Empty;
                globaldesigntenant.base64CertFile = string.Empty;


                var added = await globalDesignTenantStore.AddAsync(globaldesigntenant);
                return Ok(added);
            }
            catch (Exception ex)
            {
                string guid = Guid.NewGuid().ToString();
                var dt = new Dictionary<string, string>
                {
                    { "Error Lulo: ", guid }
                };

                telemetry.TrackException(ex, dt);
                return BadRequest("Error Lulo: " + guid);
            }             
        }



   public async Task<IHttpActionResult> DeleteGlobalDesignTenant(string id)
        {
            var telemetry = new TelemetryClient();
            try
            {
                var globalDesignTenantStore = CosmosStoreHolder.Instance.CosmosStoreGlobalDesignTenant;
                 var globalDesignTenant = await globalDesignTenantStore.FindAsync(id, "globaldesigntenants");

                KeyVaultHelper keyVaultHelperPFX = new KeyVaultHelper();
                await keyVaultHelperPFX.OnDeleteSecretAsync("GlobalDesignTenantPFXFileBAse64" + globalDesignTenant.TenantName);


                KeyVaultHelper keyVaultHelperPassword = new KeyVaultHelper();
                await keyVaultHelperPassword.OnDeleteSecretAsync("GlobalDesignTenantCertPassword" + globalDesignTenant.TenantName);

                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                var result = await globalDesignTenantStore.RemoveAsync(globalDesignTenant);
                return Ok(result);
            }
            catch (Exception ex)
            {
                string guid = Guid.NewGuid().ToString();
                var dt = new Dictionary<string, string>
                {
                    { "Error Lulo: ", guid }
                };

                telemetry.TrackException(ex, dt);
                return BadRequest("Error Lulo: " + guid);
            }
        }
1

1 Answers

2
votes

Based on my test, await keyVaultClient.DeleteSecretAsync(ConfigurationManager.AppSettings["VaultUrl"].ToString(), name) will delete the secret with specified name.

So, please set a break-point at the delete calling. Then run your application to see if it hits, and check if the parameters were expected values.