An X.509 signature certificate for the local identity provider hasn't been configured

I am implementing ISAMLConfigurationResolver to provide the configuration for IDP and SP. I am using certificate stored on my local machine when running the application on localhost however when for other environments like Development or Staging I am using CurrentUser. To achieve this I have added a conditional statement to determine the environment and pass the StoreLocation based on that. When I am running the same code on my dev environment I am getting an error.

ERROR:
An X.509 signature certificate for the local identity provider hasn’t been configured.

CONDITIONAL STATEMENT
For PartnerServiceProviderConfiguration
LocalCertificateStoreLocation = FLEnvironment.Azure ? StoreLocation.CurrentUser : StoreLocation.LocalMachine

I am pretty sure that the certificate it is locating is present in my developement env in Azure, but I am still encountering this error. Do I even have to send the StoreLocation as CurrentUser or as LocalMachine? I am a bit puzzled here.

The StoreLocation defaults to LocalMachine but can also be set to CurrentUser depending on which certificate store contains the certificate.

You also have to identify which certificate in the store by supplying one of the following: SerialNumber; Thumbprint, or SubjectName.

Is your code working on your local machine?

If so, when running in Azure, double check that you’re correctly specifying the certificate through the SAML configuration and that the certificate exists.

Yes, and this is why I am specifying the store location to be CurrentUser if I am using azure.
I am using thumbprint to identify my certificate.

public override PartnerServiceProviderConfiguration GetPartnerServiceProviderConfiguration(string configurationName, string partnerName)
{
    PartnerServiceProviderConfiguration partnerServiceProviderConfiguration = new PartnerServiceProviderConfiguration()
    {
        Name = "test",
        AssertionConsumerServiceUrl = "https://test.saml2",
        SignAssertion = true,
        SignSAMLResponse = true,
        LocalCertificateThumbprint = "mythumbprint",
        LocalCertificatePassword = "mypassword",
        LocalCertificateStoreLocation = FLEnvironment.Azure ? StoreLocation.CurrentUser : StoreLocation.LocalMachine
    };

    return partnerServiceProviderConfiguration;
}

Is your code working on your local machine?
=> Yes, it is working perfectly fine

If so, when running in Azure, double check that you’re correctly specifying the certificate through the SAML configuration and that the certificate exists
=> I have verified, and it does exist in my Azure.

I would like to point out that in Azure we have different appservices and it shares 1 keyVault and our certificates are stored in the key vault.
Could our Azure infrastructure be different than what you expect it to be, and thus it fails to locate the certificate?
I tried to debug the InitiateSSO method and other dll code but I could not dig further than the line where it uses certificateLoader to load the certificate.

I want to see the implementation of certificateLoader.LoadCertificateFromStore so that I can dig further on how you guys get a X509 certificate. We have a method of our own where we get the certificate from with currwnt user (used for Azure), so I will compare your implementation with mine, if these are uncomparable and this issue persists my last resort will be implementing ICertificateManager or I could pass the X509Certificate2 as an attribute if there is one when I am creating an object for PartnerServiceProviderConfiguration when overriding GetPartnerServiceProviderConfiguration. I also need to see the implementation of certificateLoader.LoadCertificateFromFile(certificateFile, certificatePassword) in your DLL in case I decide to use LocalCertificateFile attribute to pass the cert as a string.

Reiterating what I need from you -
I want to see the implementation of

  • certificateLoader.LoadCertificateFromStore(storeLocation, storeName, x509FindType.Value, obj)
  • certificateLoader.LoadCertificateFromFile(certificateFile, certificatePassword)
    in your DLL

We don’t make available the source code unless a license is purchased which includes the source code option. Also, I removed the decompiled code from your post. We prefer that our code isn’t shown like this and it isn’t required to resolve this issue.

Originally you were talking about the LocalMachine and CurrentUser store locations. These refer to certificates stored in a Windows certificate store.

You then said that in Azure your certificates are stored in a key vault.

Key vaults and Windows certificate stores are completely different technologies accessed in completely different ways.

If you’re storing certificates in a key vault you don’t specify a StoreLocation or SerialNumber etc. These only apply to Windows certificate stores.

The SAML library doesn’t include code for directly accessing an Azure key vault. Instead, the application is responsible for retrieving certificates from Azure key vaults and then making these available to the SAML library.

Once retrieved from Azure, there are two options for the application to make these certificates available to the SAML library.

The first is to directly specify the base-64 encoded string using the CertificateConfiguration.String property.

The second is to saved the base-64 encoded string as an application setting using .NET’s ConfigurationManager class and to specify the application setting key using the CertificateConfiguration.Key property.

You can retrieve a certificate from a key vault using the DownloadCertificate method of the CertificateClient class which is under the Azure.Security.KeyVault.Certificates namespace. Please refer to Microsoft’s documentation for more information.

Note that only certificates with private keys may be stored in Azure key vaults. This means that local certificates may be stored in a key vault. However, a partner certificate, which obviously doesn’t include the private key, can’t be stored in a key vault. You must store partner certificates some other way. One option is to use Azure blob storage.

Your GetPartnerServiceProviderConfiguration method indicates the SAML library version you’re using is at least seven years old. I strongly recommend you move to the latest version.

Also, you’re specifying the local certificate as part of the PartnerServiceProviderConfiguration. This is supported primarily to assist in staggering certificate rollover as described in the Certificate Guide. More typically, the local certificate is specified in the LocalIdentityProviderConfiguration.

To summarize:

  1. Add code to your application to retrieve the certificate from the Azure key vault, export it and save it as a base-64 encoded string.

  2. Specify the certificate string as part of the SAML configuration using the CertificateConfiguration.String property. As you’re using an old version of the SAML library the property name is probably different.