I’ve been struggling recently with trying to get following sites working correctly with SharePoint 2013 mysites. (See my forum post here). If you don’t know what functionality I am referring to, see this blog post: http://sharepoint.microsoft.com/blog/Pages/BlogPost.aspx?pID=1060. I was attempting the scenario where you have two separate farms each with their own user profile service application (UPA). This could be an intranet where mysites are located and an extranet where you are only using the UPA for AD synchronization. Or it could be two farms located in different parts of the world each with their own UPA and potentially their own mysite implementation. For me I need to be able to handle both situations simultaneously.
At first I was getting any of the following errors in the ULS logs of either server or in the message headers which I packet sniffed:
FollowedContent.FollowItem:Exception:System.Net.WebException: The remote server returned an error: (401) Unauthorized. {"error_description":"Invalid JWT token. Could not resolve issuer token."} x-ms-diagnostics: 3000006;reason="Token contains invalid signature.";category="invalid_client" x-ms-diagnostics: 3002002; reason=App principal does not exist
Luckily, after a lot of time spent getting this to work I believe I have a solution. First thing is first, all farms that need to connect need to use the same realm. In my powershell scripts below I will use the realm: myrealm. Also I’ll be using the farm names of mysitehost and collaboration where mysitehost is the farm which hosts the mysites and collaboration is the external facing farm.
First follow the first few steps here: http://technet.microsoft.com/en-us/library/ee704552.aspx on creating and copying the certs. Then run this code on the mysitehost farm (publishing farm).
$trustCert = Get-PfxCertificate "C:\ConsumingFarmRoot.cer" New-SPTrustedRootAuthority "COLlABORATION" -Certificate $trustCert $stsCert = Get-PfxCertificate "c:\ConsumingFarmSTS.cer" New-SPTrustedServiceTokenIssuer "COLlABORATION" -Certificate $stsCert $farmid = "<guid>"; #Get the farm id from the collaboration farm by typing Get-SPFarm | Select Id into powershell $security = Get-SPTopologyServiceApplication | Get-SPServiceApplicationSecurity $claimProvider = (Get-SPClaimProvider System).ClaimProvider $principal = New-SPClaimsPrincipal -ClaimType http://schemas.microsoft.com/sharepoint/2009/08/claims/farmid -ClaimProvider $claimProvider -ClaimValue $farmid Grant-SPObjectSecurity -Identity $security -Principal $principal -Rights "Full Control" Get-SPTopologyServiceApplication | Set-SPServiceApplicationSecurity -ObjectSecurity $security Set-SPAuthenticationRealm -realm "myrealm" $sts=Get-SPSecurityTokenServiceConfig $Realm=Get-SpAuthenticationRealm $nameId = "00000003-0000-0ff1-ce00-000000000000@$Realm" Write-Host "Setting STS NameId to $nameId" $sts.NameIdentifier = $nameId $c = Get-SPSecurityTokenServiceConfig $c.AllowMetadataOverHttp = $true #needed if you are not using ssl $c.AllowOAuthOverHttp=$true #needed if you are not using ssl $c.Update() iisreset Write-Host "Run Consumer Server Script and then press any key to continue ..." $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") New-SPTrustedSecurityTokenIssuer –MetadataEndpoint "http://collaboration.com/_layouts/15/metadata/json/1" –Name "collaboration metadata" -RegisteredIssuerName $nameId
Notice the section of the script that will pause and wait while you run the following script on the collaboration farm (consumer).
$trustCert = Get-PfxCertificate "C:\PublishingFarmRoot.cer" New-SPTrustedRootAuthority "mysitehost" -Certificate $trustCert Set-SPAuthenticationRealm -realm "myrealm" $sts=Get-SPSecurityTokenServiceConfig $Realm=Get-SpAuthenticationRealm $nameId = "00000003-0000-0ff1-ce00-000000000000@$Realm" Write-Host "Setting STS NameId to $nameId" $sts.NameIdentifier = $nameId $c = Get-SPSecurityTokenServiceConfig $c.AllowMetadataOverHttp = $true #needed if you are not using ssl $c.AllowOAuthOverHttp=$true #needed if you are not using ssl $c.Update() Iisreset New-SPTrustedSecurityTokenIssuer –MetadataEndpoint "http://mysitehost.com/_layouts/15/metadata/json/1" –Name "mysitehost metadata" -RegisteredIssuerName $nameId
The main difference in my scripts vs the MS documentation is I also include the registeredissuername in the New-SPTrustedSecurityTokenIssuer command (last command in each script). I was having issues with this value not being set correctly and for some reason was unable to change it after it was created.
Now on your collaboration farm, you will need to setup a separate UPA and set the trusted mysite host locations (http://technet.microsoft.com/en-us/library/ee721061.aspx). Now the way that site following works is you request a site to follow on your farm, it will look at the farm’s UPA to see find out the url of your mysite (http://mysitehost/personal/domain_userid). Then the server will basically forward your request to your mysite url’s webservice and since you are most likely using claims based authentication (best practice for SP 2013), then your claim is sent over and the request is done using your creds. So if the personal site (PersonalSpace) User Profile property is empty on your farm’s UPA, then it won’t work; you’ll get a message about your mysite is still being created. To get it to work you need to put a valid site relative path for all user’s for the personal site user profile property. I first tried using the correct value (/personal/domain_userid) and of course that worked but I also tried just putting a / for the field and that worked as well. But in the interest of correctness, I decided to implement the User Profile Replication Engine. I couldn’t find the 2013 version even though the cmdlets are documented (http://technet.microsoft.com/en-us/library/ee906542.aspx). So I had to download and install the SharePoint 2010 Administration tool kit (http://technet.microsoft.com/en-us/library/cc663011.aspx#section3). You only need to install it on one server in one of the farms. They do suggest you install it on the source server because there is less data being sent to the destination farm than being retrieved from the source farm. Below is my powershell code to sync just the personal site (personalspace) user profile property between my mysitehost farm and my collaboration farm.
Add-PsSnapin Microsoft.Office.Server.AdministrationToolkit.ReplicationEngine #Full Sync Start-SPProfileServiceFullReplication -Destination "http://collaboration.com" -Source "http://mysitehost.com" -Properties "PersonalSpace" -EnableInstrumentation #Incremental Sync Start-SPProfileServiceIncrementalReplication -Destination "http://collaboration.com" -Source "http://mysitehost.com" -FeedProperties "PersonalSpace" -Properties "PersonalSpace" -ReplicationInterval 1 -EnableInstrumentation
Now if you are just setting up an extranet where you want internal employees to be able to follow sites but external users to not have any mysite functionality other than their AD accounts are synchronized, then you are done. If you are connecting to another UPA which also has mysites and you need to be able to “share” feeds and utilize other social features, you will need to perform the same steps above as if it was the collaboration farm and a few additional steps. Make sure you perform steps 2, 4 and 5 here: http://technet.microsoft.com/en-us/library/ff621100.aspx. These would be
- On the mysitehost farm (publishing farm) publish the service application (http://technet.microsoft.com/en-us/library/ee704545.aspx)
- On the collaboration farm (consuming farm) connect to the remote service application (http://technet.microsoft.com/en-us/library/ee704558.aspx)
- Add the shared service application to the web application proxy group on the collaboration farm (consuming farm) (http://technet.microsoft.com/en-us/library/ee704550.aspx) Make sure you keep your local UPA as the default in the proxy group.
There you have it, it turns out the piece I was missing for so long was setting the realm and registeredissuername correctly on both farms so that the claim could be accepted and decrypted properly. If you are planning on connecting UPA’s from different farms where the farms do not reside in the same datacenter, please read this page on some known issues you might see: http://technet.microsoft.com/en-us/library/cc262500.aspx#geodist