SharePoint 2013 Automatically update the ADFS token signing certificate – Updated


The problem

 

One of the caveats when using ADFS as authentication provider in SharePoint is that out-of-the-box there is no way to automatically update the ADFS token signing certificate when it's changed in the ADFS server. Many times, the ADFS admins leave the ADFS certificate auto rollover enabled. This means that ADFS will automatically create a new self-signed certificate and will change the primary certificate some days before the current one expires. Unless the SharePoint admin knows when the certificate rollover will happen, which isn't usually the case, it will most probably render the ADFS authentication with SharePoint broken until the SharePoint admin realizes the certificate was changed and updates the certificate in the ADFS settings.

 

A workaround

 

At the end of this post, you can find a PowerShell script that can be run in a scheduled task. What this function does is:

  1. Using the AD FS Diagnostics PowerShell module, request a Security Token from the ADFS server in order to get the current primary signing certificate.
  2. If the current primary certificate is not already in the SharePoint trust store, it will add it to the store.
  3. Then, if the current primary certificate in ADFS is different from the current signing certificate in the ADFS login provider in SharePoint, it will update the provider to use this new certificate.

The script takes two arguments:

  • FederationServer: this is the host name of the ADFS server, for example, fs.contoso.com
  • TrustedProvider: this is the name of the AD FS login provider in SharePoint, something like "Contoso ADFS". The following PowerShell will output the names of the trusted providers configured in SharePoint: Get-SPTrustedIdentityTokenIssuer | ft Name

 

Last thoughts

 

Even if you are not using the auto certificate rollover feature in ADFS and you manually update the token signing certificate, the above PowerShell can also help to update the certificate.

Finally, the requested Security Token only includes the last certificate in the certificate chain. This means that, if the ADFS signing certificate is not self-signed, then only the last certificate in the chain will be imported into SharePoint. SharePoint documentation says that you need to import all the certificates in the chain. However, this should have been done when initially configuring the ADFS provider in SharePoint so it's not something you should need to care about when updating the certificate, unless you have changed the CA that issues the certificate.

 

Get the script from GitHub: Update-AdfsSigningCertificate.ps1

 

Comments (5)

  1. Jeroen Schoenmakers says:

    Thank you so much for this script!

  2. Querer says:

    Received the following error.

    UpdateADFSMetadata : There was an error downloading the metadata: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure
    channel.
    At line:90 char:1

    1. … do you trust your ADFS certificate? 🙂 Please check the new version of the script.

  3. Daniel Rodríguez says:

    Hello, first, thank you for the script, it points me out that the certificates ARE published in the federationmetadata.xml file and how to read them. It was very helpful.

    Just a question about code, line 46:
    $certB64 = $sts.KeyDescriptor[0].KeyInfo.X509Data.X509Certificate
    $certB64 = $metadataDoc.EntityDescriptor.Signature.KeyInfo.X509Data.X509Certificate

    It is using the same variable twice so it loses the first value. In my particular case the second signing certificate ($sts.KeyDescriptor[1]) was the good one, then for me the second line worked. In that case, ¿why check the quantity of the signing certificates? ¿why not get always the certificate from “EntityDescriptor\Signature\KeyInfo\X509Data\X509Certificate”.

    And a comment for the ones like me are trying to use this script in Sharepoint 2010. I’ve found only one command which won’t work in PowerShell v2: “Invoke-WebRequest”. This comand can be replaced by: “(New-Object System.Net.WebClient).DownloadString($metadataUrl)”.

    Thank you,
    Dani

    1. Daniel, I just modified the script to make sure we get the correct certificate all the time. Please check the new version 🙂

Skip to main content