Share via


Fixing Client secret expiration errors for Provider hosted add-in on SharePoint Online.

This post is a contribution from Mustaq Patel, an engineer with the SharePoint Developer Support team

You have a  Provider hosted add-in for SharePoint Online hosted in Azure or public facing IIS Server and it fails due to ClientSecret expiry. You will see the below error

 Invalid issuer or signature.

at Microsoft.IdentityModel.S2S.Tokens.JsonWebSecurityTokenHandler.VerifySignature(String signingInput, String signature, String algorithm, SecurityToken signingToken)

at Microsoft.IdentityModel.S2S.Tokens.JsonWebSecurityTokenHandler.ReadTokenCore(String token, Boolean isActorToken)

 

You generated new clientSecret and followed article that https://msdn.microsoft.com/en-us/library/office/dn726681(v=office.15).aspx to replace old clientsecret but the app is still failing.

Fix

First to note that https://msdn.microsoft.com/en-us/library/office/dn726681(v=office.15).aspx applies only to the ClientSecret that are not yet expired but about to expire. Since it takes 24 hours to get the ClientSecret effective, having SecondaryClientSecret (which is still unexpired) gives the app a fallback mechanism if the new ClientSecret is not effective yet.

The recommendation is that if the clientsecret is already expired and generating new clientsecret and after waiting for 24 hours still App fails with above error, it is time to clean those lingering secrets for a particular ClientId, generate a new clientSecret. Below steps will walk you through that process.

  1. Identify the ClientId for which ClientSecret is expired. You can find the clientId in Site App Permissions if the app is still installed. If not, you can find it in the web.config of the remote web application. say ClientId is 29b6b386-62a6-45c7-beda-abbaea6eecf2
  2. Connect to MSOnline using tenant admin user with below powershell in SharePoint 2013 powershell
 import-module MSOnline

$msolcred = get-credential

connect-msolservice -credential $msolcred

 

  1. Get ServicePrincipals and keys. Printing $keys will give 3 records. While running this script if you get ReturnKeyValue without any output, hit enter on powershell prompt and 3 keys will be printed.
 $clientId = "29b6b386-62a6-45c7-beda-abbaea6eecf2"

$keys = Get-MsolServicePrincipalCredential -AppPrincipalId $clientId

$keys

 

  1. Run the below command. Replace KeyId1, KeyId2 and KeyId3 from previous output.
 Remove-MsolServicePrincipalCredential -KeyIds @("KeyId1"," KeyId2"," KeyId3") -AppPrincipalId $clientId

 

  1. Confirm all the keys are deleted for the given ClientId by running #3
  1. Generate new ClientSecret for this ClientId. Please note it uses ClientId from #1. The New ClientSecret generated will have a validity for 3 years.
 $bytes = New-Object Byte[] 32

$rand = [System.Security.Cryptography.RandomNumberGenerator]::Create()

$rand.GetBytes($bytes)

$rand.Dispose()

$newClientSecret = [System.Convert]::ToBase64String($bytes)

$dtStart = [System.DateTime]::Now

$dtEnd = $dtStart.AddYears(3)

New-MsolServicePrincipalCredential -AppPrincipalId $clientId -Type Symmetric -Usage Sign -Value $newClientSecret -StartDate $dtStart  –EndDate $dtEnd

New-MsolServicePrincipalCredential -AppPrincipalId $clientId -Type Symmetric -Usage Verify -Value $newClientSecret   -StartDate $dtStart  –EndDate $dtEnd

New-MsolServicePrincipalCredential -AppPrincipalId $clientId -Type Password -Usage Verify -Value $newClientSecret   -StartDate $dtStart  –EndDate $dtEnd

$newClientSecret

 

  1. The output is the $newClientSecret. Copy it and replace the old ClientSecret with this one. Make sure ClientId in there is the same we are using throughout. Please note we don’t need SecondaryClientSecret appsettings in here.

Try browsing the app and see if it works, we have seen varied results, most of the time it works, if not wait for 24 hours to propagate ClientSecret to SPO.

 

Update

Adding links to sample scripts

https://github.com/mustaqp/SPDevSamples/blob/master/PS_SPO/CreateClientSecret.ps1 https://github.com/mustaqp/SPDevSamples/blob/master/PS_SPO/DeleteClientSecret.ps1 https://github.com/mustaqp/SPDevSamples/blob/master/PS_SPO/GetAllClientSecrets.ps1