We are using a self signed certificate to create a JwtSecurityToken. We are currently manually uploading the certificate to our Azure App Service then finding it with this code
X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
certStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certCollection = certStore.Certificates.Find(
X509FindType.FindByThumbprint,
signingCertThumbprint,
false);
return new X509SigningCredentials(certCollection[0]);
This works fine however we want to move away from having to have the certificate installed on the machine running the appservice and instead read the certificate from Azure Key Vault. The added benefit is that it means the App Service can run locally on a developers machine without the need for a certifcate to be shared and installed.
We can get the certificate from Azure Key Vault using
var certificateClient = new CertificateClient(new Uri("https://ourkeyvault.vault.azure.net/"), new DefaultAzureCredential());
var b2cInviteCertificate = certificateClient.GetCertificate("B2CInvite");
return new X509SigningCredentials(new X509Certificate2(b2cInviteCertificate.Value.Cer));
FWIW I have also tried the overload to the X509Certificate2
ctor that takes a password.
From those credentials we create a JwtSecurityToken
JwtSecurityToken token = new JwtSecurityToken(
issuer.ToString(),
audience,
claims,
DateTime.Now,
DateTime.Now.AddDays(7),
JwtService.signingCredentials.Value);
We then use JwtSecurityTokenHandler to get the token string
JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler();
return jwtHandler.WriteToken(token);
The call to WriteToken results in the folowing error message
InvalidOperationException: IDX10638: Cannot create the SignatureProvider, 'key.HasPrivateKey' is false, cannot create signatures
Why is this happening?
The reason this was not working was because the PrivateKey on the certificate retrived from KeyVault was Null. If you need the private key you need to pull the certificate as a "Secret".
This answer to Azure Key Vault Certificates does not have the Private Key when retrieved via IKeyVaultClient.GetCertificateAsync explains why and refers to another answer with much more detail