Scenario:
There are times when you are required to have a single Security Token Service (STS) (eg. AD FS) pointing to multiple WAP Tenant or Admin Portals. This is a common occurrence when you do not want to have more than one STS instance set up (possibly because it is federated with your enterprise STS and other Identity Providers that you don’t want to keep setting up repeatedly for every environment). Instead, you would like to have multiple WAP installations all pointing to a single STS instance that you can reuse. In this case you have multiple Tenant portals and multiple Admin portals from different WAP installations that need to be registered with AD FS.
When you try to set up the portals as Relying parties (RP) to the STS, the STS is going to complain after the first RP, saying you have a collision with an already existing Relying Party Identifier and will not let you set it up. This is because all your tenant portals have an out-of-the box Realm (aka Identifier) value of http://azureservices/TenantSite. The Realm value is used to uniquely identify a Relying party and the tokens issued for the user will be targeted towards that realm. Hence collisions are unacceptable. In this scenario, you have to change the realm of the portals in your different WAP installations so that they are sufficiently unique from the STS’s perspective.
Scope
- This blog post will provide information about changing the realm of a single tenant portal and does not describe changing the realm of the Admin Portal
- You can reuse parts of the post (and code snippet) to modify the realm value of the Admin Portal as well by replacing appropriate values.
Solution
The following script will modify the realm of the tenant portal. You can run it from any machine that has the Windows Azure Pack PowerShell modules on it.
Note:
- Since the point of this script is to change the Realm of the tenant portal, it assumes that you have a Tenant Authentication site as your STS. If you have AD FS, you have to modify the code snippet to add AD FS specific code to establish trust, and/or split it up into different functions.
- This script will modify the values in the WAP configuration database using PowerShell. Make sure you take appropriate backups before you execute the script.
1: $authPortalUrl = 'win-0f2kif9k2tg:30071'
2: $tenantPortalUrl = 'win-0f2kif9k2tg:30081'
3:
4: $dbServer = 'win-0f2kif9k2tg\sqlexpress'
5: $dbPassword = 'pass@word'
6:
7: $newRealm = http://azureservices/mySite
The Realm value should be in a URI format. This is per the specification for the Realm in WS-Fed Protocol. So always ensure that the realm is something of http://value/value.
Provisioning a new Realm to the portal involves 3 steps:
1. Change the Identifiers in the Portal and Service Management API databases
- Portal Config store
The Realm that will be exposed through the Federation metadata file will be specified in the Authentication.RelyingParty field under the Namespace TenantSite in the Microsoft.MgmtSvc.PortalConfigStore database in the Config.Settings table. This is a JSON value containing information about endpoints, signing certificates and Realm.
This realm needs to be updated to the new value. Note that this value is case sensitive. The following code snippet will do that for you1: $dbValue = Get-MgmtSvcDatabaseSetting -ConnectionString $portalConfigStoreConnectionString -Name 'Authentication.RelyingParty' -Namespace 'TenantSite'
2: $jsonObject = $serializer.DeserializeObject($dbValue.Value)
3: $jsonObject.Realm = $newRealm
4: $newDbValue = $serializer.Serialize($jsonObject)
5:
6:Set-MgmtSvcDatabaseSetting -ConnectionString $portalConfigStoreConnectionString -Name 'Authentication.RelyingParty' -Namespace 'TenantSite' -Value $newDbValue -Force
7:
- API Config Store
The value here will be used to validate the incoming token to validate if the token has been issued to the appropriate Relying Party. This will be specified in the Authentication.RelyingParty.Primary field under the Namespace TenantAPI in the Microsoft.MgmtSvc.Store database. This is a JSON value containing information about endpoints, signing certificates and Realm.
This realm needs to be updated to the new value. Note that this value is case sensitive. The following code snippet will do that for you1: $apiDbValue = Get-MgmtSvcDatabaseSetting -ConnectionString $storeConnectionString -Name 'Authentication.RelyingParty.Primary' -Namespace 'TenantAPI'
2: $jsonObject = $serializer.DeserializeObject($apiDbValue.Value)
3: $jsonObject.Realm = $newRealm
4: $newapiDbValue = $serializer.Serialize($jsonObject)
5:
6:Set-MgmtSvcDatabaseSetting -ConnectionString $storeConnectionString -Name 'Authentication.RelyingParty.Primary' -Namespace 'TenantAPI' -Value $newapiDbValue -Force
I have used a JSON serializer in this sample. But if you do not have access to that library, you can use ConvertTo-Json and ConvertFrom-Json PowerShell to the same effect
2. Restart the websites
You should restart the Tenant Portal and Tenant API services for the changes to get picked up. You can verify if the new value has been picked up by visiting the Federation Metadata endpoint of the portal at /federationmetadata/2007-06/federerationmetadata.xml">/federationmetadata/2007-06/federerationmetadata.xml">https://<<portalurl>/federationmetadata/2007-06/federerationmetadata.xml and validating the Realm value.
3. Establish Trust between the Portal and the STS
Once these services are restarted and the new realm value has propagated into the federation metadata, you have to re-establish trust between the portal and the STS. In the sample script provided, I have assumed that the Tenant Authentication Site is the STS. If you are using AD FS, please use the appropriate cmdlets for establishing trust.
1:Set-MgmtSvcRelyingPartySettings -Target Tenant `
2: -MetadataEndpoint https://$authPortalUrl/FederationMetadata/2007-06/FederationMetadata.xml `
3: -ConnectionString $portalConfigStoreConnectionString `
4: -DisableCertificateValidation
5:
6:Set-MgmtSvcIdentityProviderSettings -Target Membership `
7: -MetadataEndpoint "https://$tenantPortalUrl/FederationMetadata/2007-06/FederationMetadata.xml" `
8: -ConnectionString $portalConfigStoreConnectionString `
9: -DisableCertificateValidation
Once this is done, Visit the tenant portal and observe it redirect to the Tenant Authentication site. The simplest way to see if the realm was changed properly, is to observe the URL. for eg, my portal redirects to the URI:
https://win-0f2kif9k2tg:30071/Login?p=login&ReturnUrl=%2fwsfederation%2fissue%3fwa%3dwsignin1.0%26wtrealm%3dhttp%253a%252f%252fazureservices%252fmySite%26wctx%3drm%253d0%2526id%253dpassive%2526ru%253d%25252f%2526cx%253d0%26wct%3d2014-03-07T01%253a48%253a19Z&wa=wsignin1.0&wtrealm=http%3a%2f%2fazureservices%2fmySite&wctx=rm%3d0%26id%3dpassive%26ru%3d%252f%26cx%3d0&wct=2014-03-07T01%3a48%3a19Z
Note the highlighted section. This will reflect the new realm that is used by the Tenant site to identify itself. You can also validate the changed realm by looking into the database in the Config.Settings table in the Microsoft.MgmtSvc.PortalConfigStore and Microsoft.MgmtSvc.Store databases.
Summary
The Realm value is used to uniquely identify a Relying Party. So in the scenario where you have multiple WAP installations that need to point to the same STS, you should change the Realm values of these portals to unique values. You can modify the Realm value of the Tenant Portal in 3 steps
- Modifying the Realm values in the Portal Database and in the API Database stores
- restarting the services so that they can pick up the updated values. The changed value will be represented in the Federation metadata exposed by the Tenant Portal
- Re-Establish Trust between the portal and the STS