In my previous article, I discussed setting up Enterprise Federation between a single Azure AD Tenant and an AWS Cognito User Pool. One of the common questions for developers who work with Cognito is how to set it up so that it becomes possible to allow all Microsoft logins or Azure AD tenants to work with an AWS Cognito User Pool. This basically would allow a “Social Sign On” for Microsoft accounts similar to other providers like Google or Facebook.
This is a valid use case, especially for Enterprise Federation where “enterprises” quite often setup their users in Microsoft/Azure AD and if you want to allow an enterprise workforce to authenticate into your Cognito Pool, it makes sense to allow all Azure Tenants to do so, otherwise you will need to repeat the steps in the linked article above for each tenant.
Unfortunately as of the time of this writing, due to the “multi tenant” setup on Azure not being supported by Cognito for Federated providers, this isn’t possible.
In this article, I want to highlight the problem and the reason why it doesn’t work in a little more detail. In case you use or are considering Cognito for your applications, it is important to know this limitation before committing to and working with Cognito for your applications. There are workarounds, but nothing as cleaner than Cognito hopefully resolving this issue in the future.
Azure Tenants and Multi Tenancy
A quick word on Azure AD and Tenants.
Basically, an Azure AD tenant is loosely associated with an account on Azure AD. However, it is possible to configure the setup in Azure with multiple tenants.
Without getting into too much detail, roughly every account gets its own Tenant with a unique tenant id, and it can further be grouped where their user base is sub divided into multiple tenants each with its own tenant id. This is a common enough and not at all unique way of organizing things. And to reiterate, the issue is not with Azure AD.
The issue with this multi tenancy setup in Cognito
So what then is the problem?
When you setup a Federated Identity Provider in Cognito and choose Open ID Connect as the authentication exchange protocol type, one of the fields you are required to fill up is the issuer url.
When you work with Google for instance (even though AWS has a helpful Google shortcut for federated setup, you can accomplish the same by selecting OIDC and manually entering the values), the issuer url is “https://accounts.google.com“.
The fact that the issuer is static means that the OAuth JSON Web Token providing authority url – the issuer url – is a single endpoint for all Gmail logins.
In Azure AD/Microsoft though, the high level issuing url is “https://login.microsoftonline.com/common/v2.0“, however the actual response that will come back to Cognito from Azure will be of the form:
It is dynamic, because of Azure AD’s multi tenancy, when the authorization code is provided by Azure to Cognito in the case of a Federated identity setup, the issuer field in the response will come back dynamically based on which specific tenant the user account is under.
As of now, Cognito is unable to process that because it expects the issuer to match, it cannot support Azure ADs multi tenancy.
It is for this reason – the dynamic issuer value when you attempt to setup a social like sign on for Microsoft with Cognito, that it fails. You can only tie each Cognito Federated Identity Provider to a single static issuer url – associated with a single Azure AD tenant.
Are there workarounds to the problem?
Nothing as clean as hopefully having the Cognito enhancing the platform to support this out of the box.
With Cognito, one solution I have used is to have a growing list of Federated Providers for each tenant with some reworking in the front end to route users appropriately based on selecting their organization. This worked because the number of tenants was manageable but will get painful with larger growth.
There are other convoluted workarounds I have read about where the application does the authentication and validation in front of Cognito before signing users on to the pool – I personally do not recommend this – part of the reason for using Cognito is to reduce the development and maintenance overhead of the authentication flow – if you have to build solutions on top of Cognito, you have lost the benefit and also expose yourself to more security vulnerabilities. At that point, I would suggest looking at alternatives to Cognito – which unfortunately may not be as cost friendly.