Configure the API to use a Certificate

A token is required to access the Reporting API.

An access token can be obtained by calling the authentication endpoint on the API in conjunction with an API key. See Configure the Service API Key.

Alternatively, an access token can be obtained by calling the authentication endpoint using a valid certificate.

Before this can be done, you must first configure the hosting environment to use HTTPS. The certificate that you intend to use should be installed to the "LocalMachine Personal certificate store" on the host machine. Take note of the "Thumbprint" of the installed certificate, this will be needed later in the configuration process.

Once the installation is complete, you’ll need to add a new binding to configure HTTPS on the website running the CGiX Web API as follows:

  1. Load up IIS Manager and locate the Bindings for your website.
IIS Bindings

Configuration Editor in IIS

  1. Click Add in the Bindings window.
  2. Select HTTPS from the Type.
  3. Complete the Host Name field with the FQDN you want to use.
  4. Select your certificate from the SSL Certificate dropdown.
  5. Click OK to save the binding.
  6. In Windows Explorer, locate and open the "appsettings.json" file for the CGiX Web API.
  7. Update the Thumbprint setting of the CertificateConfiguration section – use the thumbprint you obtained earlier.
  8. If you would like to test this with a self-signed certificate you can set the UseChainedCertificates flag to false – we don’t advise this in a production environment.
  9. Save the changes to the "appsettings.json" file.
"CertificateConfiguration": {
    "Thumbprint": "",
    "UseChainedCertificates": true
},

Now we need to configure the client environment. For this you need a copy of the "Private Key" of the certificate installed on the hosting environment. Ask your infrastructure team to install this on your machine to the "LocalMachine Personal certificate store". Once complete, take a copy of the thumbprint as this will be needed later.

To call the API from code using the HttpClient, you must configure the certificate as a default request header using the key X-ARR-ClientCert, adding the certificate as a string to its value. Below is an example of how the certificate can be retrieved from the LocalMachine certificate store using C# and NuGet package Microsoft.Identity.Web.

public static X509Certificate2 GetCertificate(string thumbprint)
{
	var certificateDescription = CertificateDescription.FromStoreWithThumbprint(thumbprint, StoreLocation.LocalMachine);
	var defaultCertificateLoader = new DefaultCertificateLoader();
	defaultCertificateLoader.LoadIfNeeded(certificateDescription);
	return certificateDescription.Certificate;
}

In addition, you will also need to include the following headers:

HeaderDescription
UsernameThis is the CGiX user to generate the reports for e.g. “CgixReportingUser”.
CompanyIdThe CGiX company id for the provided CGiX user. For example, if user “CgixReportingUser” belongs to company with id “FSL”, then set the CompanyId to “FSL”.

This should be executed as a GET request.

Below is an example implementation of how retrieving a token can be achieved.

 protected async Task Page_Load(object sender, EventArgs e)
 {
     var certificate = CertificateUtils.GetCertificate("certificatethumbprint");

     if (certificate == null || !certificate.HasPrivateKey)
         throw new Exception("certificate not found");

     var httpClient = new HttpClient();

     var defaultRequestHeaders = httpClient.DefaultRequestHeaders;
     if (defaultRequestHeaders.Accept == null ||
         !defaultRequestHeaders.Accept.Any(m => m.MediaType == "application/json"))
     {
         httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
     }

     defaultRequestHeaders.Add("X-ARR-ClientCert", certificate.GetRawCertDataString());
     defaultRequestHeaders.Add("UserName", "CgixReportingUser");
     defaultRequestHeaders.Add("CompanyId", "FSL");

     try
     {
         var response = await httpClient.GetAsync("https://yourwebsite/api/Token/authenticateByCertificate");

         if (response.IsSuccessStatusCode)
         {
             //response.Content.ReadAsStringAsync() to get the json which contains the token;
         }
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex);
         throw;
     }
 }