Skip to content

Logging into AAD via 3rd level Federated Account

June 17, 2014

There are two common ways to authenticate into Azure O365:

  1. With non-federated account, residing in AAD, as I call it, with “managed account”, where user is authenticated against AAD using user ID and password, and with
  2. Federated account, with shadow account residing in AAD, and the account that user authenticates against, residing in the on-premises environment.

With “managed account” there are not many options, you basically authenticate against AAD, maybe have MFA on it as well. With federated account there are many variations come into play, mainly around the vendor product is being used to provide the identity provider services. AD FS is one of the most common products, but many other have been certified to provide such service as well. This topology usually assumes that user authenticates against directory where identity provider is installed. There is currently no easy way to log into the Azure via a second level Identity Provider, ie, the Identity Provider that is trusted by be on-premises IdP.

One of such ways I discussed in my blog posts back in the fall of 2013. The idea is that we register external identity provider identities in our on-premises AD DS, then use DirSync to get these registration accounts into AAD. We use AD FS to transform token from the external identity provider to use AD DS based accounts and get them authenticated into AAD. You can check out more detailed explanation on how it can be done here.

While this works, I feel like this is a bit heavy solution to provide access to the external users to AAD. Users must have accounts in on-premises AD DS, DirSync must be implemented, which means that newly registered accounts won’t be able to access AAD for quite some time. The default DirSync schedule is 3 hours and while it can be reduced, it is usually not recommended to reduce it to a small number.

So couple month ago I started thinking about other ways to use currently available technologies and be able to access AAD via external identities without using DirSync and without storing registration accounts in on-premises AD DS.

GraphAPI comes to the rescue. With GraphAPI developer can write an application that creates accounts straight in the AAD, so it is available immediately after account was registered. This is good, but how do we authenticate against it without having on-premises account? To solve this problem we can use the power of AD FS, some development and GraphAPI. As you probably know, AD FS provides support for custom attribute stores (CAS). CAS is basically a way to pull information about the user from external data stores (not from AD DS, AD LDS or SQL), like text files, other LDAP directors, or as you can guess where we are going, from the AAD itself. All we need to do is to write CAS that uses GraphAPI to query our AAD Tenant for user information and then builds a SAML token that will be passed to the AAD for authentication.

To do this we need to create a mapping between the external identity and the AAD based account. One of the easiest way of doing this is to take user Name Identifier claim from the external IdP, make sure its value is less than 64 characters and put in into the ImmutableID attribute of the user account in AAD – this should be done during registration of the user in AAD. As part of registration unique UPN will be generated as well, this is a required attribute of the user account.

After the mapping between the external account and AAD account is done, we’ll configure CAS to use Name Identifier as the lookup value of the user account in the AAD to find its corresponding UPN. Now AD FS will have required information to build the outgoing SAML token to authenticate to AAD – user UPN and ImmutableID.

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: