Setting up Cross-Farm Federated Service Applications
Setting up cross-farm federated service applications without the frustration
If you need to set up cross-farm federated service applications in SharePoint 2010 you usually find yourself looking at one of many fairly complex PowerShell scripts that can be found on the Internet. The problem with this particular activity is that different parts of the script need to run on each farm, so it isn't really possible to come up with a self-contained script that you can just run. And in this case it is particularly confusing, so it is easy to run the wrong part on the wrong server, or get certificates mixed up, or generally to get into a mess. It gets difficult to figure out which step went wrong when you reach the end and you get a stubborn error message when you try to use your federated service application.
Personally, I prefer to do most of the work in SharePoint Central Administration. For me, the main advantage is that I can see what is going on, and that helps me understand what it is doing. At each step I can see that everything is okay. A few people have asked me how I do this, so I have recorded the steps here, with the warning that I have only checked it on SharePoint 2010 SP1. If you are using an older version of SharePoint I can't guarantee that it will all work. That's not a problem with SharePoint but with my memory.
Getting certified
First, we need to create a set of certificates, and for that we will use PowerShell, as there is really no other way. We need to put these certificates in a place accessible to the other farm, e.g. a share. Remember that the consuming farm requires the root certificate of the publishing farm, but the publishing farm needs both the root certificate and the STS (Security Token Service) certificate for the consuming farm. Let's suppose we have two farms called the services farm (the publisher) and the intranet farm (the consumer). A key thing here is to give these certificates descriptive names so that we can easily find the right one when we use them later.
On a server in the publishing farm we need to run the following script to create the root certificate:
(Get-SPCertificateAuthority).RootCertificate.Export("Cert") |
Set-Content "\\\\share\\ServicesFarmRoot.cert" -Encoding byte
On a server in the consuming farm we need to run the same script to create its root certificate:
(Get-SPCertificateAuthority).RootCertificate.Export("Cert") |
Set-Content "\\\\share\\IntranetFarmRoot.cert" -Encoding byte
In addition, still on the consuming farm, we also need to generate the STS certificate:
(Get-SPSecurityTokenServiceConfig).LocalLoginProvider.SigningCertificate.Export("Cert") |
Set-Content "\\\\share\\IntranetFarmSTS.cert" -Encoding byte
A question of trust
Now that we have created the certificates we are pretty much done with PowerShell. Everything else can be done from Central Administration. First we need to set up trusts, starting with the consuming farm which must trust the publisher. On the consuming farm go to Central Administration->Security->General Security->Manage Trust. Use the New button in the ribbon to create a new trust relationship and name it "ServicesFarm" (i.e. this farm trusts the services farm). Click on the Browse button for the Root Certificate and find the ServicesFarmRoot certificate you created above. Click OK. Your Intranet farm now trusts the Services farm - you do not need to provide an STS certificate for the publisher farm.
Over at the publisher farm, again go to Central Administration->Security->General Security->Manage Trust. Create a new trust relationship as before and name it "Intranet Farm" and browse to the root certificate as before, this time choosing the IntranetFarmRoot certificate. In addition you need the STS certificate for the consuming farm, so check the "Provide Trust Relationship" checkbox and use the Browse button to navigate to the IntranetFarmSTS certificate. Click OK. You now have a two-way trust relationship between the Services and Intranet farms (publisher and consumer).
Publish and be damned
The next step is to publish services from the publishing farm. Go to Central Administration->Application Management->Service Applications->Manage service applications. Select the Application Discovery and Load Balancer Service Application (aka. the Topology service) and click on Publish in the ribbon and check the Publish check box. Take note of the URL for the topology service, which you will need later. This will be of the form https://servername:32844/Topology/topology.svc. You can keep a copy of this, or if you can memorize the port number (which is always the same) you should be able to reconstruct this URL from first principles when you need it (don't forget that it is the https protocol).
Click OK, and while you still have this service application selected you can click on the Permissions button in the ribbon and give the consumer farm access to the topology service. This can be either the farm id or the farm account of the consuming farm. To get the GUID corresponding to the farm ID of the consuming farm you need to use PowerShell again (running on a server in the consuming farm):
(get-spfarm).Id
Enter the GUID for the farm id or the farm account (in the form domain\\account, e.g. corp\\sp_farm) in the input box and click the Add button. Once it is added, select it and check the Full Control checkbox, and click OK.
Now go to the service application management page on the consuming farm and click on Connect in the ribbon and enter the URL for the topology service of the publishing farm, as mentioned above, and then click the OK button. If everything is set up correctly you should get another dialog box entitled "Connect to a Remote Service Application". It will probably say that there are no service applications available because none have been published yet. If you get an error message you know that either the trusts are not set up correctly, or the topology service is not published or has incorrect permissions.
At your service.
Now that you have set up the connection, you also need to publish each of the required service applications and give the consumer farm permissions to them. On the publishing farm select the service application you want to publish (e.g. Managed Metadata Service) and click on Publish in the ribbon, and check the box and click on OK. You also need to give the consuming farm appropriate permissions. Select the service application again and click on the Permissions button. This is similar to the permissions on the topology service and again you can use either the farm id (although this doesn't work for User Profiles and is probably not sufficiently restrictive for production use) or use the farm account and the application pool account(s) of the consuming farm's web applications. Don't forget to check the boxes for any granular permissions for the particular service application as required.
If you go back to your consumer farm you should now be able to use the Connect ribbon button as before and this time you should see the published service applications listed. If they are not there it means you have not published it. Select the required service application and click on OK to create the connection.
Once the connection is created, you should be able to access the management and properties pages, although not all service application connections allow this. If you get an error when you try to use the management or properties pages (and the service application is working in the publishing farm) it is usually because the permissions have not been set correctly.