Multi-tenant Azure AD federation with PowerShell
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 theAzure 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.
*Create a federated user in Azure AD *
[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'
http://www.ruudborst.nl/wp-content/uploads/2015/06/ToBase64String.jpg
AD User ObjectGuid to Base64 string
http://www.ruudborst.nl/wp-content/uploads/2015/06/immutableid.jpg
ImmutableID set on the Azure AD user
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.
Create a federated domain without touching ADFS
$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
http://www.ruudborst.nl/wp-content/uploads/2015/06/Federateddomain1.jpg
Federated Domain modified with settings from the code above
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.
Blog source: http://www.ruudborst.nl/multi-tenant-azure-federation-without-dirsync-aadsync-aadconnect-fim