I've created the Key Vault and entered a secret. When I run my services locally using .NET, I am able to retrieve the secret via the key vault. Here's what I did: 1) Created an SSL certificate 2) Used that SSL certificate to create an AD application 3) Created a Service Principle for the above application 4) Gave full key vault access to this application 5) I put the VaultURI, ServicePrincipal.Application ID, and the cert thumbprint in the Web.config file 6) I also uploaded the *.pfx of that cert to my cloud service
When I run my service locally, I am able to retrieve the secret. I have even tried retrieving the secret via powershell and I have been successful. When I deploy my code to Azure, I am unable to retrieve the secret.
It says:
Type : Microsoft.Azure.KeyVault.Models.KeyVaultErrorException, Microsoft.Azure.KeyVault, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 Message : Secret not found: QSAccounts7126 Source : Microsoft.Azure.KeyVault Help link :
I have spent 3 days looking at it and retesting every possible scenario and haven't figured out what is wrong. Can someone please help in identifying the issue or directing me in the right path for debugging? I even tried publishing the cloud service in debug mode in Azure, and for some reason that did not work either.
Any help you can provide would be greatly appreciated.
private async Task<string> getSecretConnection(string connectionName)
{
var kvName = ConfigurationManager.AppSettings["vaultName"];
var kvClientId = ConfigurationManager.AppSettings["clientId"];
var kvClientThumbprint = ConfigurationManager.AppSettings["clientThumbprint"];
using (keyVaultHelper = new AzureKeyVaultHelper(kvClientId, kvClientThumbprint, kvName))
{
var bundle = await keyVaultHelper.GetAzureKeyVaultSecretAsync(connectionName);
return bundle;
}
public async Task<string> GetAzureKeyVaultSecretAsync(string secretName)
{
var bundle = await this.KvClient.GetSecretAsync(KeyVaultUrl, secretName);
return bundle.Value;
}
This is the code that runs for authentication:
private async Task<string> getAccessTokenFromSPNAsync(string authority, string resource, string scope)
{
//clientID and clientSecret are obtained by registering
//the application in Azure AD
var certificate = CertificateHelper.FindCertificateByThumbprint(this.ClientThumbprint);
var assertionCert = new ClientAssertionCertificate(this.ClientId, certificate); //needed for authentication
var clientCredential = new ClientCredential(this.ClientId, this.ClientThumbprint);
var authContext = new AuthenticationContext(authority, TokenCache.DefaultShared);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, assertionCert);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the token from Azure AD using certificate");
}
return result.AccessToken;
}
WEBSITE_LOAD_CERTIFICATESequals thumbprint values in the Azure WebApp appsetting. In that case your certificate will be loaded to your web applications personal certificate store. More details you could refer to this blog. - Tom Sun - MSFT