Provider-hosted add-ins stop working and HTTP 401 error

Symptoms

Consider the following scenarios.

Scenario 1

  • You are preparing to implement provider-hosted add-ins or use Workflow Manager in a Microsoft SharePoint 2013 or Microsoft SharePoint 2016 farm.

Scenario 2

  • You have existing, deployed provider-hosted add-ins (PHA) that are registered as <RegisteredIssuerName> and that contain the original farm RealmID value for your SharePoint 2013 or SharePoint 2016 farm, or you created a Workflow Manager association in your farm.

In this scenario, when you access these PHAs after you configure SharePoint hybrid features in your farm, the PHAs stop functioning. Additionally, you receive an HTTP 401 error message when you are directed to the add-ins.

Cause

Configuring SharePoint hybrid features for SharePoint 2013 or SharePoint 2016 disrupts server-to-server (S2S) trusts that are created before you implement hybrid features. When you try to establish an S2S trust by using the Cloud SSA on-boarding script or the Hybrid Picker, the on-premises farm's authentication realm is updated to match the Office 365 tenant context ID. The script sets the authentication realm by using the Set-SPAuthenticationRealm cmdlet. After the authentication realm is changed, existing SharePoint add-ins fail to authenticate.

This authentication failure occurs because of how provider-hosted add-ins are authorized to access SharePoint. SharePoint add-ins are associated with SPTrustedSecurityTokenIssuers by using the IssuerId value. On request, an add-in tries to get a token from the Secure Token Service issuer (STS). The token issuers are tied to the authentication realm. After the realm is changed, the SharePoint add-ins can no longer authenticate successfully. The trusted token issuer that has the correct issuer ID still exists in the farm. However, it is associated with the previous authentication realm. The actual <RegisteredIssuerName> value is IssuerId@OldAuthRealmGuid, in which the oldAuthRealmGuid value no longer matches the current AuthRealmGuid value. The add-in fails to authenticate because the STS can’t find a matching token issuer.

The following error message is logged to ULS logs and clearly indicates that the token issuer is no longer trusted because its RealmID value no longer matches the farm:
SPApplicationAuthenticationModule: Failed to authenticate request, unknown error. Exception details: System.IdenitytModel.Tokens.SecurityTokenException: The issues of the token is not a trusted issuer.

Resolution

To resolve this problem, use the appropriate method for your scenario.

Scenario 1

Implement hybrid workloads that require S2S before you implement the provider hosted add-ins or Workflow Manager. The add-ins will then be registered after the SPAuthenticationRealm cmdlet is updated to match the Office 365 tenant context ID. They’ll always work because the RealmID value won’t change again. If hybrid workloads are added or reconfigured, the realm ID remains the same as the Office 365 tenant context ID.

Scenario 2

When you implement Hybrid, RealmID is changed to match the tenant ID of your Office365 subscription. This causes add-ins to stop working, as explained in the "Symptoms" section. To restore SharePoint add-in functionality, reregister the provider-hosted add-ins by using the <RegisteredIssuerName> value that contains the new realm ID. Then, reapply the add-in permissions for each add-in instance.


The Workflow Manager TrustedSecurityTokenIssuer value uses a wildcard realm identifier (for example, “@*”) instead of a specific realm identifier. Therefore, workflows continue to function after SPAuthenticationRealm is changed.

To repair authentication-related issues that are associated with provider-hosted add-ins and hybrid features, follow these steps:

  1. Run the following query to discover all the app instances that are deployed on a web application:
    Add-PsSnapin Microsoft.SharePoint.PowerShell
    $webApp = Get-SPWebApplication "https://sharepoint.yourwebapplication.com"
    foreach($site in $webApp.Sites){
    Write-Host $web.Url -BackgroundColor DarkGreen
    foreach($web in $site.AllWebs)
    {
    $appInstance = Get-SPAppInstance -Web $web.Url | select Title,Appwebfullurl,AppPrincipalId, Id, LaunchUrl
    if($appInstance -ne $null)
    {
    $appInfo = $appInstance.Title + " - " + $appInstance.Appwebfullurl + " - " + $appInstance.LaunchUrl + " - " + $appInstance.AppPrincipalid + " - " + $appInstance.Id
    Write-Host $appInfo
    }
    }
    }
  2. Run SPTrustedSecurityTokenIssuers by using the following script:
    $NewRealm = Get-SPAuthenticationRealm
    $sts = Get-SPTrustedSecurityTokenIssuer | ? {$_.Name -ne 'EvoSTS-Trust' -and $_.Name -ne 'ACS_STS'} [A1] | Select RegisteredIssuerName
    $realm = $sts | ?{$_.RegisteredIssuerName -ne $null} | %{$($($_.RegisteredIssuerName).toString().split('@',2)[1]).toString()} | ?{$_ -ne '*' -and $_ -ne $newRealm}

    if($Realm.count -gt 0) {
    $TempRealm = '*@$($NewRealm)'
    $Issuers = Get-SPTrustedSecurityTokenIssuer | ?{$_.Name -ne 'EvoSTS-Trust' -and $_.Name -ne 'ACS_STS' -and $_.RegisteredIssuerName -ne $null -and $_.RegisteredIssuerName -notlike '*@`*' -and $_.RegisteredIssuerName -notlike $TempRealm}

    $Guid = [guid]::NewGuid()
    foreach ($Issuer in $Issuers)
    {
    $NameCopy = $Issuer.Name
    $NewIssuerName = $Guid
    $IssuerCertificate = $Issuer.SigningCertificate
    $OldRegisteredIssuerID = $Issuer.RegisteredIssuerName
    $IssuerID = $OldRegisteredIssuerID.Split('@')[0]
    $NewRegisteredIssuerName = $IssuerID + '@' + $NewRealm
    $NewIssuer = New-SPTrustedSecurityTokenIssuer -Name $NewIssuerName -Certificate $IssuerCertificate -RegisteredIssuerName $NewRegisteredIssuerName -IsTrustBroker
    Remove-SPTrustedSecurityTokenIssuer $Issuer -Confirm:$false
    $NewIssuer.Name = $NameCopy
    $NewIssuer.Update()
    }
    }
  3. Fix each provider-hosted add-in that was found in step 1 by running the following script:
    $appDisplayName = '{0}'
    $clientID = '{1}'
    $targetWeb = Get-SPWeb '{2}'
    $Scope = 'Site'
    $Right = 'FullControl'
    $authRealm = Get-SPAuthenticationRealm -ServiceContext $targetWeb.Site
    $AppIdentifier = $clientID + '@' + $authRealm
    Register-SPAppPrincipal -NameIdentifier $AppIdentifier -Site $targetWeb -DisplayName $appDisplayName
    $appPrincipal = Get-SPAppPrincipal -Site $targetWeb -NameIdentifier $AppIdentifier
    Set-SPAppPrincipalPermission -Site $targetWeb -AppPrincipal $appPrincipal -Scope $Scope -Right $Right
To update the authentication realm for Workflow Manager, follow these steps:

  1. Run the following cmdlet:
    $workflowproxy = Get-SPWorkflowServiceApplicationProxy
    $webapp = get-spwebapplication
    if ($webapp)
    {
    $webappurl = $webapp[0].url
    $Site=get-spsite $webappurl
    if ($site)
    {
    $workflowaddress = $workflowproxy.GetWorkflowServiceAddress($site)
    $workflowscopename = $workflowproxy.GetWorkflowScopeName($site)
    $TrimScope = '/'+$workflowscopename+'/'
    $wfmaddress = $workflowaddress.TrimEnd($Trimscope)
    }
    }
    $workflowproxy.delete()
    Register-SPWorkflowService -SPSite $Site -WorkflowHostUri $wfmaddress -Force
  2. If you deployed cross-farm trust scenarios before you configured hybrid features, use the methods in the following TechNet topics to fix the scenarios manually:

More Information

To create a server-to-server trust between your SharePoint on-premises environment and Office 365, run the  SPAuthenticationRealm cmdlet. For more information, see Set-SPAuthenticationRealm.

To create SharePoint provider-hosted add-ins, see Get started creating provider-hosted SharePoint Add-ins.

To learn more about the Set-SPAuthenticationRealm cmdlet, see Set-SPAuthenticationRealm.

Properties

Article ID: 4010011 - Last Review: 2017, ജനു 10 - Revision: 11

ഫീഡ്‌ബാക്ക്