We have an application running on a VM in our Service Fabric service in Azure.
To communicate with one of our partner's Rest APIs, we need to use a client certificate. (_restClient.ClientCertificate = ...)
So my first attempt was to add the Certificate (pfx, including a private key) to our Azure Key Vault. And then the application receives it from the Key Vault. However ,I don't seem to be getting the private part of the certificate, which is needed to sign the package. This question, Is it possible to get the private key out of Azure Key Vault Keys?, also seems to try the same thing without success.
I also found this article: Use an SSL certificate in your application code in Azure App Service. However, that only seems to handle the case when you run a Web App from an App Service. But since I don't use that, I don't understand if this can be applied in my case.
So how do I get ahold of the ClientCertificate from Azure that I need to use in my RestRequest?
You are on the right track. once you have certificates in your key vault all you need is a key vault client to get certificate from there, which you can assign to your rest client.
this link has enough info to help you get the complete certificate from your vault
Related
I am currently working moving from using App Services to Azure Kubernetes Service for a group of APIs running in .Net Core. It is all going well with the exception of Azure Key Vault, so I am hoping that somebody can help me out.
I need to store database connection strings for each of these APIS securely, so have chosen to use Azure Key Vault, but I am not actually sure why or if the Secrets Store CSI driver is necessary for what we are aiming for. Can we not just create an access policy in Azure Key Vault for the AKS node to have access too to retrieve the key? Or just use a managed identity? I can then use the Key Vault SDK in the app code.
If anyone can shed some light on this I would really appriciate it as I just seem to be coming across the CSI driver in all documentation/videos I find. If we do need to use it, I would just like to know why so I have a better understanding.
I have tried using the CSI driver, as well as trying to retrieve without the CSI driver. At the moment I am struggling to get either to work. However once I know if I need the CSI driver, I can go with the correct approach, as currently I am bouncing around between different ones.
Thanks in advance!
Both options (injecting secrets using the Secrets Store CSI Driver or fetching them directly from the vault in the application using .NET SDK) are perfectly valid options.
The secrets store CSI driver acts as an intermediate layer between the application and the key vault and makes the secrets from the vault available to the application as either files or environment variables. The secret store driver uses a managed identity attached to the underlying scaleset to access the key vault.
This means that:
The application becomes independent of how the keys are stored at rest, which makes it easier to test locally as well as deploy in environments other than Azure.
The application does not need to have access or manage credentials to the key vault since the secrets is pushed into the container where the applications runs by the CSI driver (as opposed to being pulled in by the application itself)
When using the Azure SDK your application will connect directly to the key vault and there is no need for an intermediate component, but this couples your application tightly to Azure Key vault. You also end up with the challenge of how to provide credentials to your application to authenticate to the key vault. Since those credentials cannot be stored in a key vault, you need another construct providing you an identity, like AAD Pod Identities or the newer Azure AD workload identity. So even though you don't use the Secret Store CSI driver you will most likely need another component to facilitate authentication to the key vault.
I've been reading a lot lately about managing secrets with Azure Key Vault. I managed to create and install a .pfx certificate in a server with Ubuntu 20.04 and uploaded the certificate to my Azure AD following these steps.
The certificate is found correctly before connecting to my Key Vault and the secrets are retrieved when I am in development both from Windows and Linux (WSL). However, when I deploy the app to my production server, the service I created to manage kestrel throws a 'core-dump' error, similar to this issue.
But in my case, when I check the journal, I find the following:
Unhandled exception. System.InvalidOperationException: Sequence contains no elements
Surprisingly, this doesn't happen if I just manually run the application by using "dotnet app.dll".
How is this even possible? It opens the store, finds the certificate and access the secrets if I run it manually but doesn't find anything when is run by the service.
This is the relevant code I am using to configure the access to Key Vault in my Program.cs:
// Azure Key Vault configuration.
using var store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindByThumbprint, configuration["KeyVault:AzureADCertThumbprint"], false);
configuration.AddAzureKeyVault(
new Uri($"https://{configuration["KeyVault:KeyVaultName"]}.vault.azure.net/"),
new ClientCertificateCredential(configuration["KeyVault:AzureADDirectoryId"], configuration["KeyVault:AzureADApplicationId"], certs.OfType<X509Certificate2>().Single()),
new KeyVaultSecretManager());
store.Close();
Can anyone help me to find the issue? Thanks in advance.
I checked some Microsoft docs and I didn't found anything wrong with code to access the key vault. I guess you may forget something in application setting on portal, as your code has no problem.
After creating your certificate, configure Azure AD and associate the certificate after that we can access Azure Key Vault from .NET Client using X509 Certificate.
After importing the certificate and casting Certificate Data to Base64, we should create Azure Resource Manager AD Application and Service Principal. Successfully configuring Azure Resource Manager Application and Service Principal for an Azure Key Vault could solve the problem you are facing.
Check this Accessing Azure Key Vaults Using Certification and Setup Key Vault using Azure AD Application and Certificates for more information.
I have created a Blazor WebAssembly app with a server backend using Identity Server out-of-box (from the template).
I want to publish it to Azure but I don't get it working with loading the certificate from Azure KeyVault.
I have used the wizards in Visual Studio to generate the boilerplate code. Everything has been configured too.
And I read this guide too: https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/hosted-with-identity-server?view=aspnetcore-5.0&tabs=visual-studio#host-in-azure-app-service-with-a-custom-domain
And I have created a certificate in the Key Vault named IdentityServerSigning with CN=IdentityServerSigning.
When I then run the app I get 500.30.
Opening the Web-based Console from the Portal, I launch the app and get that it could not find a valid certificate 'CN=IdentityServerSigning' on the 'CurrentUser/My'.
What am I missing?
I guess you may forget to add application setting on portal, if your code has no problem.
We need to give Azure App Service permission to use the newly uploaded certificate. For that:
Go to Configuration in the menu of your Azure App Service
Click on New application setting
In Name, put: WEBSITE_LOAD_CERTIFICATES
In Value, put the Thumbprint that you copied from the previous section.
Click Ok, and don’t forget to click Save
If it doesn't work, pls read below blogs, you will find out the issues.
Suggestion
You can refer to this blogs to check the steps, I believe it will useful to you.
Blazor: Using a Self-Signed Certificate for IdentityServer4 in Azure App Service
To load the cert from Azure Key Vault in IdentityServer 4, you can use ActiveLogin:(https://github.com/ActiveLogin/ActiveLogin.Authentication)
More here: https://github.com/IdentityServer/IdentityServer4/issues/2705
I'm working on securing some Azure Functions endpoints. I tried with Certificate, but I hit a few walls
In the FunctionsStartup (from which derives my startup) I could not find a way to connect my AddAuth and Auth methods/classes. (I tried to search, read more on this topic, but all the answers were either for web API other type of Authentications)
I tried to check for the existence of a certificate at least, but that didn't worked either. I tried to get the certificate from request-context-connection-ClientCertificate or to read it from headers. Didn't worked locally or on deployed version. The certificates are always null.
I saw that there are some options to secure it with AD(also with facebook, google and so on), but first I'm curious if someone successfully implemented another Auth method, more like in a classic web api approach (JWT tokens, certificate, other similar stuff)
Access restrictions enable you to define a priority ordered allow/deny list that controls network access to your app. The list can include IP addresses or Azure Virtual Network subnets. When there are one or more entries, there is then an implicit "deny all" that exists at the end of the list.
Also you can request a client certificate when the client request is over TLS/SSL and validate the certificate. This mechanism is called TLS mutual authentication or client certificate authentication.
First, your App Service plan must be in the Basic, Standard, Premium, or Isolated tier.
Secondly, enable client certificates:
az webapp update --set clientCertEnabled=true --name <app_name> --resource-group <group_name>
Finally, Access client certificate. App Service injects an X-ARR-ClientCert request header with the client certificate. Your app code is responsible for validating the client certificate.
For more details about how to configure TLS mutual authentication for Azure App Service, please refer to this article.
I'm integrating my app with Xero which requires two certificates. I uploaded them to Azure with help from this article, but I'm still unable to connect to the Xero API. I'm hoping someone has experience integrating a Xero Partner Application with an Azure Web App.
I've uploaded two pfx files; one is a self-signed certificate and the other is the partner certificate issued by Xero. The latter pfx file contains two certificates; an Entrust Commercial Private Sub CA1 (whatever than means) and a unique Entrust Id certificate for my app.
I'm using the following code to load the certificates by their unique thumbprint:
static X509Certificate2 GetCertificateFromStore(string thumbprint)
{
var store = new X509Store(StoreLocation.CurrentUser);
try
{
thumbprint = Regex.Replace(thumbprint, #"[^\da-zA-z]", string.Empty).ToUpper();
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
var currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
var signingCert = currentCerts.Find(X509FindType.FindByThumbprint, thumbprint, false);
if (signingCert.Count == 0)
{
throw new Exception($"Could not find Xero SSL certificate. cert_name={thumbprint}");
}
return signingCert[0];
}
finally
{
store.Close();
}
}
This works fine locally, but on my azure web site I get a 403.7 error:
The page you are attempting to access requires your browser to have a Secure Sockets Layer (SSL) client certificate that the Web server recognizes.
I've also looked at the following references to try and resolve the issue:
Xero Partner SSL configuration in Azure (Uses a cloud service and not a web app, so I couldn't follow the steps at the end)
403 Forbidden when loading X509Certificate2 from a file (Thread posted on the Xero forums about the same issue, figured out that the resolution is only for once again; cloud services)
Xero partner connections and Azure Websites (Posted solution suggests using a VM)
What I haven't tried yet:
Converting my web app to a cloud service; trying to avoid doing this however I'm not sure what steps are involved.
Using a VM; I haven't found any detailed steps on how to do this but seems like a better option than above.
Screenshot of the error:
A 403 error means we are not seeing the Xero Entrust certificate in the connection.
More details about it here - http://blog.xero.com/developer/api-overview/http-response-codes/#403
Basically , It runs on your local IIS instance because it is a "single tenant" machine where your application doesn't need to be isolated from others.
While you application is blocked by the security model used to isolate web sites.
In summary, you have to do the following to get your certificates working on Azure:
1) Export the certificate, private key, and all intermediary certificates into a PFX file.
2) Upload the certificate using the Azure portal to the cloud service that you're running (it should appear as multiple entries).
3) Access the certificate through the machine store in code.
Based on data taken from:
https://community.xero.com/developer/discussion/626401
https://social.msdn.microsoft.com/Forums/azure/en-US/29b30f25-eea9-4e8e-8292-5ac8085fd42e/access-to-certificates-in-azure-web-sites
I hope it solved your issue.
Finally got this working and I will post my solution which will hopefully save developers a lot of time and frustration when connecting with Xero.
The Xero Partner Application will not work with Azure App Services (Web Sites). You have to upload two additional certificates along with your self-signed and the Xero partner certificate. These can be found on your local machine and can be exported in cer format (details of these certificates below). Not being able to upload these certificates for Azure app services is indeed the crutch. They also have to be uploaded to specific stores (Root/CA), which you cannot do with app services. These are the steps I took to connect with Xero.
Converted my web site to Azure Cloud Services: I was weary of changing our environment as we already have a live site. It turns out that cloud services is essentially the same as app services; you still are deploying to a VM somewhere. However, you have more control over the back end and you can remote desktop in. Read more here. Used links below to create and convert my website to cloud services:
Create a new cloud service project
Convert existing web site to cloud service
Uploaded 4 certificates to my cloud project using the azure portal. You will need to upload the following:
Your self-signed certificate (the one you created here)
The partner certificate issued by Xero (you probably got it here)
The Intermediate Entrust certificate (this one should be contained within the .p12 file you downloaded above)
The Entrust Root certificate (this should be in your Trusted Root Store**)
Added the certificates to my Web Role in the Cloud project. You have to right click on the properties of your web role and go to the certificates tab. Add all 4 certificates to your web role using the thumbprint which will be visible in the portal after you uploaded them. Take note of the Store Name for the two entrust certs:
You may have to adopt a lot of patience as I have to get through step one. You'll have to figure out the new deployment process, how to debug your project locally, and probably a lot of other frustrating tidbits!
**This is the correct Entrust Root certificate you can get by using certmgr.msc:
Make sure you added the application setting from step 2 of your referenced article.
Adding an app setting named WEBSITE_LOAD_CERTIFICATES with its value set to the thumbprint of the certificate will make it accessible to your web application. You can have multiple comma-separated thumbprint values or can set this value to “ * “ (without quotes) in which case all your certificates will be loaded to your web applications personal certificate store.
I'd also be more specific in specifying the certificate store, i.e. use:
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
This is how we load certs in all of our Azure Web Apps.