0

I have an app which uses certificates ( Uploaded the cert) in Azure Azure KeyVault.

I am trying to use asp.net application 4.7 to connect to key vault and retrieve the application Certificate and the Secret associate with it

Previously I used Microsoft.Azure.KeyVault and KeyVaultClient in combination with GetCertificateAsync and GetSecretAsync to pull the certificate and its secret.

However I recognized that Microsoft.Azure.KeyVault is deprecated so i researched and I found That I should use Azure.Security.KeyVault.Certificates instead.

I wrote the below code New Way:

using Azure.Security.KeyVault.Certificates; public static X509Certificate2 GetCertificateFromVault(string keyVaultName, string certificateName) {

       var keyVaultUri = $"https://{keyVaultName}.vault.azure.net/";


        var client = new CertificateClient(new Uri(keyVaultUri), new DefaultAzureCredential());

        KeyVaultCertificateWithPolicy keyVaultCertificateWithPolicy = client.GetCertificate(certificateName);
        return new X509Certificate2(keyVaultCertificateWithPolicy.Cer);
    }

However I get error on calling client.GetCertificate(certificateName); in above code which is my new way Here is the error

Multiple exceptions were encountered while attempting to authenticate. ---> Azure.Identity.CredentialUnavailableException: E nvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n
at Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex, String additionalMessage)\r\n at Azure.Identity.EnvironmentCredential.d__12.MoveNext()\r\n

I have KeyVaultCertificateOfficer role and I can retrieve the certificates using my old way on the local machine so I am sure I do not have access issue.

I looked at developer guide it says that I need to create environment variables for AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID Is that the solution? I do not understand why? Do I need to do this on all my different environment like UAT and PROD and create these variables. I kind of dont like that so i think i missing something here.

If I absolutely need to create env variables also not sure what to use as AZURE_CLIENT_SECRET as I use Certificate not secret for my App. I saw AZURE_CLIENT_CERTIFICATE_PATH but that is the path to pfx in local machine right which we do not want that.

Maybe my understanding is totally wrong I am not sure. So any guidance would be much appreciated!

user464291
  • 127
  • 11
  • 1
    I think when you're using DefaultAzureCredential, see this answer https://stackoverflow.com/questions/70616431/how-to-use-defaultazurecredential-in-both-local-and-hosted-environment-azure-an. There's a good Microsoft explanation for this. – MZM Dec 14 '22 at 00:43
  • Thank you so much for the response. Above link suggest to create Manage identity. How ever I have an on premise application , The app pool identity account ( It is a service account in ad which is synced to azure Ad ) currently has access to key vault. I want to use my existing service account that has already access to key vault instead of creating managed identity which is brand new entry in Ad is that possible? And if it is I wonder how? – user464291 Dec 14 '22 at 16:14
  • I can use the following to get the secrets from the vault with out any env variable – user464291 Dec 14 '22 at 23:39
  • public static string GetSecretFromVault(string keyVaultName, string secretName,string tenantId, string clientId) { var keyVaultUri = $"https://{keyVaultName}.vault.azure.net/"; //used ClientSecretCredential instead of DefaultAzureCredential() var client = new SecretClient(new Uri(keyVaultUri), new ClientSecretCredential(tenantId: tenantId, clientId: clientId, clientSecret:"123")); var secret = client.GetSecret(secretName); return secret.Value.Value; } – user464291 Dec 14 '22 at 23:46
  • How ever i am not sure how to do this using certificate instead of application Secret. I veleive if i want to use ClientCertificateCredential i need to have pfx on local machine – user464291 Dec 14 '22 at 23:49
  • With Microsoft.Azure.KeyVault I couldhave passed the certificate name and get the identifier and from there get the secret. I need to do the same with Azure.Security.KeyVault.Certificates any idea on that? – user464291 Dec 14 '22 at 23:52
  • Actually 7- identity options, DefaultAzureCredential combines some classes, that are used to retrieve AAD identity. It tries to initialize them one by one (in this order). The first successfully initialized credential is used: EnvironmentCredential,ManagedIdentityCredential,SharedTokenCacheCredential,VisuaStudioCredential,VisualStudioCodeCredential,AzureCliCredential,InteractiveBrowserCredential. https://www.rahulpnath.com/blog/defaultazurecredential-from-azure-sdk/ - https://learn.microsoft.com/en-us/azure/developer/java/sdk/identity-azure-hosted-auth#default-azure-credential – MZM Dec 15 '22 at 00:02
  • var client = new CertificateClient(vaultUri: new Uri(vaultUrl), credential: new DefaultAzureCredential()); - in this example 2nd parameter shouldn't be the default Azure Credential to prevent from using 7-Identity options in the previous comment, but service account credential, possibly new DefaultAzureCredential(azureCredentialOptions) from rahulpanth.com in comment above. – MZM Dec 15 '22 at 00:26
  • Thanks for your respond. I tried the below code using the link you mentioned no luck. In the docs it says DefaultAzureCredential is used for application that in cloud. Maybe that is why var keyVaultUri = $"https://{keyVaultName}.vault.azure.net/"; var azureCredentialOptions = new DefaultAzureCredentialOptions(); azureCredentialOptions.SharedTokenCacheUsername = "ADD User Account"; var client = new CertificateClient(new Uri(keyVaultUri), new DefaultAzureCredential(azureCredentialOptions)); var cert = client.GetCertificate("Cert-D-CC-KV-test"); – user464291 Dec 16 '22 at 21:16
  • I still get the error still get error DefaultAzureCredential failed to retrieve a token from the included credentials. EnvironmentCredential authentication unavailable. – user464291 Dec 16 '22 at 21:17

1 Answers1

0

Create a key Vault and certificate in azure

enter image description here

enter image description here

And we have chosen the same .Net4.7 Framework

enter image description here

Used the NuGet package "Azure.Security.KeyVault.Certificates

enter image description here

The below namspaces are used in the application

using Azure.Identity;
using Azure.Security.KeyVault.Certificates;
using System.Security.Cryptography.X509Certificates;

Below is the code used for fetching the certificates from azure

 string certificateName = "TestCertificate";
 var KeyVaultUri = @"https://KeyVaultName.vault.azure.net/";
 var client = new CertificateClient(new Uri(KeyVaultUri), new DefaultAzureCredential());
 KeyVaultCertificateWithPolicy keyVaultCertificateWithPolicy = client.GetCertificate(certificateName);
 var res= new X509Certificate2(keyVaultCertificateWithPolicy.Cer);

Certificate details are fetched in below screens

enter image description here

enter image description here

Rajesh Mopati
  • 1,329
  • 1
  • 2
  • 7