When talking about external identities in Azure, it is usually all those guest users who are involved, whether they belong to partner organizations, subsidiaries or service providers is not important.
If these so-called B2B users are to be provisioned in certain enterprise applications in AzureAD (user provisioning of B2B Azure users in SAAS application), this presents the Azure administration with a number of challenges. This makes it all the more important to adapt the selection of the future application and requirements management to such challenges.
To better understand this, here is a short "DeepDive" into the process of such provisioning in AzureAD. If you are already familiar with this process, you can also jump directly to the How-To.
To provision users for SAAS applications via the Azure AD Provisioning Service, a SCIM (Cross-Domain Identity Management Endpoint) is required on the part of the SAAS provider. If this is not provided, the provisioning service will not be able to talk to the other side via this API. We assume that the SCIM is present in the SAAS application.
Initial scenario: Our guest users have already been manually added to the Azure Tenant via an invitation link or via previously configured automations. These users are also in the designated groups that will be selected for provisioning later. It is also important to note that guest users should not receive an M365 license. A possible provision of an AzureAD P1 or P2 license (e.g. for MFA etc.) is possible but not mandatory. Microsoft has a new licensing procedure "MAU" here, which licenses guest users.
In order to provide the SAAS application with the required attributes of the AzureAD guest user, this data is provided to the SAAS application via the attribute mapping configured by the administrator in the Enterprise Applications area. As shown in the figure above, the user data is sent to the Provisioning Service via the GraphAPI. In the background, the service links the received user data to the required attributes in the SAAS application and sends the user data to the SAAS application via the Target-API-Connector. In addition to the synchronization of the pure values behind the attributes, value manipulations can also be performed in the synchronization process. This is helpful if the SAAS application needs the attribute values in another form. However, it can also bear the risk that duplicated, identical values flow into the SAAS application and links are no longer correct, unless there is a control process on the application side or in the mapping that checks for uniqueness of the value. To avoid this problem you should find an attribute for the mapping of the user in AzureAD in advance, which is unique and can act as a user identifier attribute. In my following best-practice solution for guest user deployment this can be achieved in most cases with the AzureAD attribute OriginalUserPrincipalName.
In my daily work as an IT architect I have already connected various SAAS applications to an AzureAD for user provisioning. But each SAAS application requires different requirements as to how the user data is received by the application. A good example is the SAAS application Atlassian Cloud from the software manufacturer Atlassian. Using the Atlassian Cloud as an example, I would like to show you my best practice strategy for user provision via AzureAD, with a focus on B2B users. Because if you want to work in SAAS applications with partners or service providers invited via the AzureAD, there is no way around a well thought-out strategy.
The best practice strategy for a user deployment using Atlassian Cloud.(Note: in the best practice strategy, due to time constraints, I do not go into every point on how to fully configure such an integration with AzureAD. For more information, please refer to Microsoft's official documentation or contact the SAAS solution vendor).
Reading through the tutorial on Configuring Automatic User Provisioning for Atlassian Cloud in the Microsoft documentation, the user mapping requires the following, most important attribute for successful mapping from Atlassian Cloud:
Atlassian Cloud uses this attribute to uniquely authenticate the user provided by AzureAD when logging in. If you later enable the SSO functionality, the claim nameidentifier references the attribute. Back at the user provisioning, however, this attribute is not the only criterion that must be met for the provisioned users from the AzureAD to be visible and fully functional in the Atlassian Cloud. Thus, the users must still additionally arrive in the Atlassian Cloud with a domain-verified email address in the already mentioned "emails" attribute. This sounds quite simple at first, if one owns the domain and thus the required TXT record entry for validation is quickly set. However, for invited guest users (Azure B2B guest users) this turns out to be a bit more difficult. After successful onboarding in Azure, external guest users first have the external email address on the userprincipalname attribute via which they were originally invited. And it is exactly the value of this attribute that Atlassian Cloud wants to preserve, according to Microsoft documentation.
If you run the user provisioning test, you quickly notice that the guest users are not discoverable in the Atlassian Cloud, but the provisioning service in AzureAD has not necessarily reported an error. The cause is quickly explained. In this case, the provisioning service was able to successfully submit the user data to the Atlassian Cloud via the API interface, but on the other hand, the Atlassian Cloud had not found any validated domains in the provided email addresses of the users here and thus skipped the process with the following error in the log:
User with ID 6903457-1a8c0-4a34-8ef8-78763423038b7, primary email email@example.com, is not a managed user
From this moment on it is literally "break the rules". The documentation doesn't help us much anymore, and Atlassian support currently only provides a link to an open feature request.
The following options are still available to us on the Azure side:
Transformation of the Azure attribute to the desired validated domain
Assigning another AzureAD user attribute to the Atlassian attribute "email".
A transformation is not the best solution for this attribute, which is unique to Atlassian Cloud. There could be multiple mappings to an Atlassian identity, as briefly mentioned earlier, because there is no control structure to check.
So the only option left is the last one, mapping a different AzureAD user attribute on the Atlassian attribute "email"
And here Microsoft has given us a solution in the bag, which I think can be considered for many such problems.
Every user, whether guest or user gets an email address with the initial tenant domain provided during onboarding in Azure. For guests, the setup looks like this:
Since the initial Tenant domain is ours and we have access to the DNS settings, we can also validate it in Atlassian Cloud alongside our other custom domains. With this solution, all AzureAD users now have a validated email address and can be successfully deployed to Atlassian Cloud.
The only remaining questions are, which AzureAD attribute hides the email address with the initial default domain and how is a complete email flow for notifications out of Atlassian products ensured?
With the found place in the Microsoft documentation the attribute topic is also quickly off the table. Since the attribute "userPrincipalName" for guest user objects does not contain #EXT# one should use the source attribute "originalUserPrincipalName" instead. The value here remains intact and assembled.
In order for the notifications from the Atlassian products to reach the external mailboxes of the guest users, the following attribute and value must be set for the MailUser object:
However, it is important to note here: before the command can be executed, the guest user must be set to "Member" for the "UserType" attribute. For security reasons, the value of the UserType can be reset to "Guest" after the configuration.
Set-AzureADUser -ObjectId XX -UserType Member
This makes the user an "Email-User". He can now be edited in the Exchange and is thus also listed under the contacts in the Admin-Center of the Exchange.
To enable the mail flow via Exchange Online to the external mailbox of the guest user, the attribute "PrimarySMTPEmailAddress" must have the following default value.
To check whether this is the case, we can output the MailUser object with the single value only.
Connect-ExchangeOnline (if no session is active anymore)
Get-MailUser -Identity (can be UPN,Emailadresse or the Name) | select PrimarySmtpAddress
If the expected value is not displayed, it can be adjusted subsequently.
$PrimarySmtpAddress = Get-MailUser -Identity (can be UPN,Emailadresse or Name ) | select PrimarySmtpAddress
Set-MailUser -Identity (kann UPN,Emailadresse oder der Name sein) -PrimarySmtpAddress $PrimarySmtpAddress
Since the ExternalEmailAddress attribute has the same value as the PrimarySmtpEmailAddress by default, the value must also be changed here finally.
$ExternalEmailAdress = Get-MailUser -Identity (can be UPN,Emailadresse or the Name) | select OtherMail
Set-MailUser -Identity (can be UPN,Emailadresse or the Name) -ExternalEmailAddress
However, a little patience is required. The mailflow usually does not work immediately. So it can take up to 30 min. for a test mail to reach the external mailbox via the SMTP email address.