Update: Added a multi-tenant PowerShell provisioning script to the TechNet gallery with examples mentioned in this blog. Download here.
Introduction
Microsoft is advocating their own synchronization tools (DirSync/AADSync/AADconnect/FIM) to federate with Azure AD. There are a lot of advantages using a synchronization tool, this way companies don’t need to develop their own solutions, it’s easy deployable, has a lot of out-of-the-box two way sync options and pretty much the way to go for most companies. These tools are mainly used for AD synchronisation with Office365 using Azure AD and built for one tenant businesses only. But demand for on-premise mult-tenancy support is growing, that’s because Microsoft recently begun actively onboarding larger companies and Cloud Providers into their Microsoft Cloud Solution Provider (CSP) program and of course the ever growing cloud adoption. These larger companies may have other requirements before they are ready to onboard their own customers or departments with Office 365 and Azure. One of these requirements may be leaving the authentication and objects on-premise, this could be because of company policy enforcing them to manage multifactor, audit or password authentication policies in their own cloud. Or they just want to leave their customers in their own directory for a variety of well-founded reasons like investments in own infrastructure, single sign-on, security, trust, regulation or legal issues.
In this federated scenario the authentication of federated user identities in Azure are redirected to the ADFS servers belonging to the company’s own AD. By using their own directory as the authentication and synchronization source they are also able to combine or cross-sell not only Office 365 services but also other federation ready services like Google+, SalesForce etc. And since they are hosting multiple customers or tenants a multi-tenant solution is key to their success and that’s precisely what is not yet available in any Microsoft synchronization tool. But luckily Microsoft or do I have to say Azure made federation functionality available in Azure PowerShell and in the Azure AD Graph API. But there is a catch, if you want to implement the whole federation package then you have to do your research and development and do a lot of testing to make it compatible with your environment. I didn’t find a source yet where all the multitenant federation pieces came together, so I hope to solve the puzzle here if you’re going for the PowerShell way. This solution allows you to onboard your multitenant AD environment to a multitenant Azure AD environment, provisioning multiple tenants with multiple federated domains across multiple subscriptions.
Magical attribute
An Azure AD synchronization tool allows you to use a filter to select which objects and object properties to sync to the selected objects (users) in Azure AD. But is also able to tie these on-premise users to the Azure AD users by using a rather unique Azure AD attribute. The Azure AD user is considered federated when this attribute is set.
This is the magical ‘ImmutableID‘ attribute, it’s still unknown to many Azure AD admins and also some Microsoft employed consultants are not aware of its significance and how to use it with PowerShell. And since you are reading this on my blog it’s not surprising what I’m going to say now! Yesssss, you can set the attribute yourself and tie an on-premise user to an Azure AD user with the Azure PowerShell module with just one line of code! But you can also use the cool Azure AD Graph REST API to set the ‘Immutable ID‘, you can find a PowerShell sample here and there is even a well written PowerShell module.
The ‘ImmutableID’ attribute value is set with the user’s on-premise ‘objectGUID’ converted to a base64 string. When the user signs in and the ImmutableID atrribute is set, Azure AD identifies the user as a federated user and then looks at the domain portion of the sign-in address (UPN), if the domain portion matches a configured federated domain the Azure federation server redirects the user to the configured ADFS server login site for that domain.
The ADFS server converts the ImmutableID attribute back to the ObjectGUID and hard matches (claim rule) the on-premise user in Active Directory, combined with the soft match of the user’s UPN sign-in address ADFS correctly authenticates the user and passes a successful authentication token containing a series of claims back to the Azure AD federation server.
1 2 3 |
[guid]$Guid = "21c956c1-bb8c-4d27-8d5h-528dg3f09114" $base64 = [System.Convert]::ToBase64String($guid.ToByteArray()) New-MsolUser -ImmutableId $base64 -UserPrincipalName 'john@customer.com' -Password 'S0m3PasSw0rd' -PasswordNeverExpires $true -FirstName 'John' -LastName 'Doe' -DisplayName 'John Doe' -UsageLocation 'NL' -LicenseAssignment 'customer:O365_BUSINESS_PREMIUM' |
Multitenant solution
This provisioning approach allows you to federate multiple on-premise tenants with multiple Azure AD tenants using your own multitenant provisioning logic which is not supported if you use a synchronization tool. You control which on-premise user belongs to which Azure AD user, this user can exist in another subscription as long as you’ve got the credentials to access that subscription. And there you go, your own multitenant provisioning solution without extra layers of software in between, something where every self-respecting ‘Cloud Provider’ or large Enterprise company dreams about! But unfortunately that’s not the complete story, you also need to configure the federated domains so Azure knows where the ADFS server is located for that user and last but certainly not least if required, set-up attribute synchronization.
Federated domains
You need to configure an Azure domain as a federated domain before Azure AD redirects the ‘ImmutableID’ set federated user to the on-premise ADFS server for authentication. This sounds straightforward in theory but in practice pretty unclear how to properly configure this with multiple tenants and multiple federated domains. First you’ll have to configure your ADFS server for multiple domains if you want to enable multitenancy. This is done by specifying the ‘SupportMultipleDomains’ parameter to the ‘New-MSolFederatedDomain’ cmdlet when you provision your first federated domain. The cmdlet requires you to execute locally on your ADFS server, the cmdlet/module then tries to make an explicit separate connection from your internal ADFS server (not the proxy) to Azure to verify, retrieve and set the settings needed to make the domain federated. After that it retrieves the ADFS configuration url’s plus the code signing certificate and configures this information for the federated domain in Azure. Already created a federate domain and want to modify your existing federated setup then take a look at my blog post here.
The ‘MsolFederatedDomain’ cmdlet requires you to have an internet connection to Azure for your internal ADFS servers, this is very uncommon from a security perspective point of view. Especially if you used ADFS Web Application Proxies in front of your ADFS servers which are an essential part of every secure ADFS deployment. Of course you could try to proxy the request to Azure AD but that doesn’t work because the cmdlet actually creates a direct TCP connection to Azure circumventing any system set (netsh/IE) proxy. Thus leaving you setting up a gateway with a static route to the required IP space in Azure just so your ADFS server can set and verify the federated domains with Azure. Don’t get me wrong, I understand why Azure implemented this solution just as with a synchronization tool everything is handled and verified by programmed logic to make it all easier and more supportable but just won’t do and aren’t tailored for larger secure multitenant environments. If you’re in the cloud/hosting business for quite a while then this isn’t particularly new for you and the story continues again by creating workarounds and developing own solutions. But that’s still something what challenges me and love to find out, so after some rigorous testing and exploring the Azure module cmdlets I found a very poorly documented way to bypass the whole thing and configure the same federation url’s and certificate settings the cmdlet does without even touching the ADFS server. Also take notice of the ‘$domain’ variable in the ‘issueruri’ below, this url is translated by the third claim rule added by the ‘-SupportMultipleDomains‘ switch and allows ADFS to identify multiple domains.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$Domain = 'customer.com' # Create new federated enabled domain New-Msoldomain -Name $Domain -Authentication Federated # Retrieve and set TXT record in DNS $TXTrecord = (Get-MsolDomainVerificationDns -domain $Domain).label -replace "\..*","" $TXTrecord = 'MS=' + $txtrecord # ADFS Federation Settings $Brand = 'Contoso' $ActiveSO = 'https://sts.contoso.com/adfs/services/trust/2005/usernamemixed' $PLUri = 'https://sts.contoso.com/adfs/ls/' $IssuerUri = "http://$Domain/adfs/services/trust/" # NOTICE the $Domain variable $Metadata = 'https://sts.contoso.com/adfs/services/trust/mex' # Public key of the ADFS code signing certificate, this is an example $Cert = "MIIC3jCCAcaGAwIBAiIQZy18ai4/1qNKekSKawAD2jBNAgkqhkiG9w0BAQsFADArMSkwJwYDVRRDEyBBREZTIFNpZ25bpmcgLSBzdHNud1Vya29ubG..SHORTENED..fXunm6+Tp0e11zorVaeA4nu46fAKnf9+E/Iumw1GcC/Kca4T+8SaWp8Zjip74zCY4zPOQ" # Confirm domains TXT record in DNS and set federation properties Confirm-MsolDomain –DomainName $Domain -FederationBrandName $brand -PassiveLogOnUri $PLUri -SigningCertificate $Cert -IssuerUri $IssuerUri -ActiveLogOnUri $ActiveSO -LogOffUri $PLUri -MetadataExchangeUri $metadata |
Attribute Synchronization
Of course without using a synchronization tool you’ll have to use your own (PowerShell/.NET) solution to synchronize specific AD attributes like displayname, title, function etc to Azure AD. Luckily in my situation all platform provisioning is done using PowerShell and .NET only without using any third party components like a control panel or such. I integrated the missing ‘synchronization’ part in my existing ‘update user information’ function which updates the user attributes not only in the on-premise AD but also in Azure AD when that user also has the Office 365 service enabled. Updating a user in this way is also another huge benefit over a synchronization tool because your own provisioning is the source of all creation, removal and modify actions in your AD. The provisioning engine directly sets the modified information in Azure AD instead of waiting for a periodic synchronization when using a synchronization tool. In this situation you don’t have any reason to use synchronization at all, only if there is a real showstopper. In my terminology that simply means that you can’t use the same API, endpoint or method what other software is using and thus have to rely on third party software. Of course the software also has to be in compliance with your company requirements such as security, redundancy, stability and performance, particularly if it interacts with one of the most important security related data the company owns.
Therefore a word of advice, be careful before you commit yourself to more and more layers of software, keep your provisioning solution secure, fast, simple and transparent. Don’t let yourself be misguided by well-intentioned advice from other people, take some time, dig deep and you’ll find a solution geared for your environment.
Conclusion
Using the code snippets from above combined with your own provisioning system logic, you’re able to onboard a multitenant AD environment to a multitenant federated Azure AD environment, provisioning multiple tenants with multiple federated domains across multiple Azure subscriptions. Implementing the code requires some good understanding about ADFS and Azure AD or Office 365 PowerShell provisioning, without the basic knowledge it can be difficult to extend it to a complete provisioning solution containing all the other available provision/deprovision operations. The more companies using this provisioning aproach, the less chance Micorosoft is ever deprecating the functionality only extending it. See comments below this post about supportability.
I hope the inner workings and understanding of multitenant federation in Azure is quite clear now and you’re not missing any essential puzzle pieces. If so then feel free to comment or email me, and while you’re at it also follow me on Twitter to get notified of future Azure posts. Depending on the reception, I will consider to write a second article about Federation in combination with SSO, so please retweet!
4 comments
Skip to comment form ↓
Jon Bryan
June 22, 2015 at 12:44 (UTC 2) Link to this comment
Ruud,
Thanks for leaving a comment in the “Multi-forest and Multi-tenant scenarios with Office 365” TechNet article. I thought it best to bring my discussion here….
From what I gather, I can simply put two DirSync servers into place – with filtering for each tenancy – so only the correct people are sync’ed. I’m happy to use two DirSync’s – it keeps things simple and easy to support.
Looking at the code “Create federated domain without touching ADFS”, this seems to be fairly simple.
So, in my case, if I change the existing federation to support multiple domains, I can then run your sample script (with edits) for the other tenancy to allow them to login via the same ADFS farm? Is that all I need?
Thanks,
Jon.
Ruud Borst
June 22, 2015 at 15:38 (UTC 2) Link to this comment
Hi John,
That’s right! But officially you’ll have to delete the relying party trust on your AFDS server manually and recreate that trust using ‘update/new-MSOLFederatedDomain’ cmdlet with the ‘-SupportMultipleDomains’ switch.
More info here: http://blogs.technet.com/b/abizerh/archive/2013/02/06/supportmultipledomain-switch-when-managing-sso-to-office-365.aspx
But I’ve got good news, I just posted a new blog with two code snippets to modify the trust with the third claim rule supporting multiple domains and code converting existing federated domains using the same parameters as specified in the ‘Create federated domain’ snippet. This way you won’t have to delete the trust and don’t run into any update problems.
http://www.ruudborst.nl/azure-federation-manually-modify-support-for-multiple-domains/
Thanks for your feedback!
Ruud
Jon Bryan
June 23, 2015 at 18:13 (UTC 2) Link to this comment
Ruud,
Very nice!
However, I guess that from a MS POV, this is a completely unsupported configuration?
My management would be very wary…. :(
Are you running this in your production environment?
My reply from MS support was:
“As far as I know, we have not such scenario regarding one ADFS farm which is federated with 2 tenants. As I mentioned, we have not published related article regarding how to deploy it (step by step). Thanks for your understanding.”
See: https://community.office365.com/en-us/f/613/p/355103/966153#966153
Regards,
Jon.
Ruud Borst
June 24, 2015 at 11:16 (UTC 2) Link to this comment
Hi Jon,
Thing is that ADFS supports multiple domains, so you are able to federate multiple domains, that’s totally supported. It also means that this way ADFS can federate with a federated domain from Office365 Tenant1 subscription and a federated domain from Office365 Tenant2 subscription. ADFS just does the authentication part and doesn’t care if you’re coming from another tenant or from a second federated domain configured on the same tenant. It just translates the immutableID part and UPN back to the user in AD for which it has to do the authentication for.
The questionability in regard to Microsoft supporting this scenario lies in setting the ImmutableID attribute for users in multiple tenants with other software then a Microsoft synchronization tool. They allow you to do it via the Azure AD PowerShell module and via the Azure AD Graph REST API which allows you to do even much more and my best guess and what would be recommended practice is that a synchronisation tool like AADConnect also uses this API for operations against Azure AD like setting the ImmutableID. This scenario combined with setting multiple federated domains with ADFS config supporting multiple domains yourself without MS controlling or knowing your solution is clearly out of there boundaries and reasonably not supported. As a vendor this is understandable, but you are using and setting the attribute and configure a federated domain as if you’re using it for one tenant and that’s supportable. I hope this is somewhat clear and of course this is what my experience tells me and not officially from Microsoft or Azure themself. Let’s just hope they are reading this blog and make some haste with true multinancy support in the new AAD connect.
Ruud