This post is in follow up to a previous post about setting up an OAuth trust between two farms: http://blogs.technet.com/b/speschka/archive/2012/07/23/setting-up-an-oauth-trust-between-farms-in-sharepoint-2013.aspx. The primary reason for writing that post was to describe how to set up an OAuth trust between two farms, which can be used for a number of reasons. A secondary part of that post was to describe the process of setting up a Remote SharePoint Index, which is one of the top reasons why you would create that trust. What I have since discovered is that this type of trust by default will only return search results from the web application with which the trust is created. For example, as the post indicates you run some PowerShell that looks like this:
$i = New-SPTrustedSecurityTokenIssuer -Name FARMB -Description "Farm B" -IsTrustBroker:$false -MetadataEndPoint "https://farmb.foo.com/_layouts/15/metadata/json/1"New-SPTrustedRootAuthority -Name FARMB -MetadataEndPoint https://farmb.foo.com/_layouts/15/metadata/json/1/rootcertificate$p = Get-SPAppPrincipal -Site https://www.foo.com -NameIdentifier $i.NameIdSet-SPAppPrincipalPermission -Site https://www.foo.com -AppPrincipal $p -Scope SiteSubscription -Right FullControl
In this case, the results you would get back would only be those items that are contained in the https://www.foo.com web application. If you have multiple web applications, or other non-SharePoint content sources, they won't be returned in the search results when queried remotely. Side Note: this limitation does not exist when you are using Remote SharePoint Index in a hybrid situation between Office 365 and an on-premises SharePoint farm. So, how do we get results from all our web applications and content sources? Well there are two things we need to do: 1) create additional realms and grant the SPAppPrincipal permissions to it and b) when you grant permissions, set the scope to SiteCollection instead of SiteSubscription.
Let's look at a concrete example: suppose you are in Farm A, and you have 3 web applications: https://portal.foo.com, https://teams.foo.com and https://my.foo.com. (Another side note: please don't interpret this to mean that you should have multiple web applications in SharePoint 2013 - you should try and use one web app and host name site collections, and add web apps if business requirements dictate). Farm A is going to trust Farm B, and Farm B is going to send queries to Farm A. In Farm A then, we need to set up a realm for each of the three web applications and grant permissions to the SPAppPrincipal that Farm B will use when issuing the queries. We'll start out with the first two lines of PowerShell, which are the same as our original post:
$i = New-SPTrustedSecurityTokenIssuer -Name FARMB -Description "Farm B" -IsTrustBroker:$false -MetadataEndPoint "https://farmb.foo.com/_layouts/15/metadata/json/1"New-SPTrustedRootAuthority -Name FARMB -MetadataEndPoint https://farmb.foo.com/_layouts/15/metadata/json/1/rootcertificate
Now that we have our reference to the SPTrustedSecurityTokenIssuer for Farm B, which is in our variable $i, we can use that when granting rights to each of the realms we create. So to create the realms, we do this for each of the web applications:
#this first line only needs to be done once
$realm = $i.NameId.Split("@")
#then do this for each web application
$s1 = Get-SPSite –Identity https://portal.foo.com$sc1 = Get-SPServiceContext -Site $s1Set-SPAuthenticationRealm -ServiceContext $sc1 -Realm $realm$p = Get-SPAppPrincipal -Site https://portal.foo.com -NameIdentifier $i.NameIdSet-SPAppPrincipalPermission -Site https://portal.foo.com -AppPrincipal $p -Scope SiteCollection -Right FullControl
Once you've completed this for https://teams.foo.com and https://my.foo.com, you will be able to issue queries from Farm B and get results from all of your content sources in Farm A. That includes your SharePoint content sources as well as non-SharePoint sources.
Good information on Sharepoint 2013
Great post, thanks!
Just to verify, but with remote index I assume you mean a farm that is not on-premises (i.e. not in the same network, domain, etc. as the farm that should be indexed)?
Hi @Harrie, a remote index could be on-premise in another geo, it could be just another farm in the same data center, or pretty much anything in between.
Ok great, thanks! I was always under the impression things like App Management, configuring app principal permissions and so on would only be required when using custom apps, on-premises < >Office 365, etc.
I'm extensively looking into this with MS Support, since I'm struggling to get content following to work (which works apart from when following people) in a cross-farm (services farm + content farm) scenario.
Thats a great reference. What is the best architecture to set remote indexing farm dedicated for crawling huge file shares close to 2 TB?
Will remote Publishing farm with 1 App server and 1 SQL server with additional realms and scoped to site collection will be enough for optimum performance or 2 app servers (1 for index and 1 for Query) is needed?
Is there any way to set up services only farm for crawling remote file shares? How to configure Set-SPAppPrincipalPermission for this scenario since there is no site collection?
Will thi also work if the remote farm is a Sharepoint 2010 farm. I.e. querying the sharepoint 2010 search index from sharepoint 2013 search?
Do you need to do this when you have a services farm and conusming farm? Where you have already exchanged the trust certificates?
can this be done between a SharePoint Server 2013 farm and SharePoint Foundation 2013 farm in a way, that the Server farm shows content crawled by the foundation search service? I assume users will always use the server farm for querying.
Great post Steve - I have one question though, what if you wanted add a to the mix can you use the same approach?
That should read "if you wanted to add a Farm C or more" but it was stripped out!