Configuring a multi-tenant federation with AD FS in a multi forest scenario with PowerShell

For weeks we have been working with Microsoft Premier Support and several product teams within Microsoft on a multi-forest to multi-tenant federation solution for Office 365 at two Dutch municipalites. There was some unclarity concerning supportabilty for our desired architecture at Microsoft, but as Microsoft calls it… this architecture qualifies for supportabilty. The fun part is, this scenario doesn’t require the provisioning of AD objects by hand, and allows you to use AADConnect to do this for you!

Now as the topology shows, we have two accounting forests where the AADConnect servers and Active Directory users reside. Each municipality has its own forest (forest B and forest C) and a configured a two-way full trust (forest-wide) to the resource forest (forest A). The Active Directory Federation Services (AD FS) farm resides in the resource forest (forest A).

Now the business requirement is having a single but high available AD FS farm in a resource forest, delivering an easy way of administering Identity Management for the long term. While at the same time delivering single sign-on functionality to all users working with Office 365 for each respected municipality.

Now the hard part here is the second federation to Office 365. The first federation configurated between the Microsoft Federation Gateway and your on-premises AD FS farm is pretty straight forward. And here is how it’s done:

  1. Log in to one of the AD FS Servers with an Domain Administrator account.
  2. You need to install the modules that are required for Office 365,
    1. Microsoft Online Service Sign-in Assistant for IT Professionals RTW
    2. Windows Azure Active Directory Module for Windows PowerShell (64-bit version
  3. Setup a Remote PowerShell connection to your tenant with an account having Global Administrator rights with this script;
    1. Import-Module MSOnline
      $O365Cred = Get-Credential
      $O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $O365Cred -Authentication Basic -AllowRedirection
      Import-PSSession $O365Session
      Connect-MsolService –Credential $O365Cred

Once connected to the first tenant in Office 365 on the AD FS server run this cmd-let, be sure to use the -SupportMultipleDomains $true parameter.

Convert-MsolDomainToFederated -DomainName contoso.com -SupportMultipleDomain $true

The –SupportMultipleDomain parameter is needed since this is required for the multi-tenant configuration to work. This paramater makes sure that the federation is built with the correct IssuerUri set to https://contoso.com/adfs/services/trust/ instead of the Federation Service namespace (generally sts.domain.com) when not using this parameter. This is a vital requirement later on. To double-check this you can check the Claim Rules in AD FS management, the third rule should containt this claim:

c:[Type == “http://schemas.xmlsoap.org/claims/UPN“] => issue(Type = “http://schemas.microsoft.com/ws/2008/06/identity/claims/issuerid“, Value = regexreplace(c.Value, “^((.*)([.|@]))?(?<domain>[^.]*[.].*)$”, “http://${domain}/adfs/services/trust/“));

Now this was the first municipality for which contoso.com is the federated domain. You can download the script at the bottom of this blog.

Wait for a minute -or five- untill the federation kicks in and let’s carry on implementing the second federation…the real fun part!

First of all we need to export the token-signing certificate from the AD FS farm by PowerShell:

$tokenRefs=Get-AdfsCertificate -CertificateType Token-Signing
$tokenBytes=$certRefs[0].Certificate.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Cert)
[System.IO.File]::WriteAllBytes(“c:\temp\tokensigning.cer”, $certBytes)

Next we can establish a new Remote PowerShell session to the second tenant with the script shared in step one of this post. After that we configure the second federation with this PowerShell script.

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2(“C:\temp\tokensigning.cer”)
$certData = [system.convert]::tobase64string($cert.rawdata)
$dom=”fabrikam.com”
$url=”https://adfs.ResourceForestFDQN.com/adfs/ls/&#8221;
$uri=”http://fabrikam.com/adfs/services/trust/&#8221;
$ura=”https://adfs.ResourceForestFDQN.com/adfs/services/trust/2005/usernamemixed&#8221;
$logouturl=”https://adfs.ResourceForestFDQN.com/adfs/ls/&#8221;
$metadata=”https://adfs.ResourceForestFDQN.com/adfs/services/trust/mex&#8221;
#command to enable SSO
Set-MsolDomainAuthentication -DomainName $dom -Authentication Federated -ActiveLogOnUri $ura -PassiveLogOnUri $url -MetadataExchangeUri $metadata -SigningCertificate $certData -IssuerUri $uri -LogOffUri $logouturl -PreferredAuthenticationProtocol WsFed

Now the most beautiful part of this second implementation is that it only configures endpoints on the Microsoft Federation Gateway, and doesn’t touch our on-premises configuration. The magic third claim we talked about earlier is all we need for it to work!

Once configured, the configuration of both tenants can be validated using the ‘Get-MsolDomainFederationSettings’ cmdlet. The only difference when comparing the tenant configuration should be the ‘FederationBrandName’ and the ‘IssuerUri’ values.

Download the PowerShell scripts right here!