Using ADFS to “fix” an Azure AD custom SAML connection

I recently had to sort out an issue with a customer that was using an application with a home-grown SAML stack.

Note: This generally ends in tears, Do not write your own SAML stack. Rather use one of these.

The problem was that this stack would only accept one connection per issuer. So if e.g. you had custom SAML providers for Dev, Test and Prod. on the same Azure AD tenant (which by definition has the same issuer i.e. the tenant ID) the stack would throw an exception.

There are three ways to fix this:

  • Have a different Azure AD tenant for Dev, Test etc. This would be a logistical nightmare in terms of synchronising the user provisioning, groups etc across them all.
  • Bridge the connection with another IDP. This would have a different issuer. This would need a separate IDP per connection but it’s a one-off operation.
  • Fix the SAML stack bug. This was the long-term answer.

Due to time constraints, we opted for a bridge and since the customer runs a Microsoft shop, we used their ADFS.

The flow is then:

Azure AD app panel → Azure AD → (SAML) → ADFS → (SAML) → Application

Adding ADFS into the mix allows you to do all kinds of other things because you now have claims rules.

e.g. the UPN for a guest account looks like:

joe@gmail.com#EXT#azure-domain.com

The application did not like this format. Using ADFS claims rules with regex, you can strip off everything after the “#” getting a UPN of:

joe@gmail.com

To configure the Azure AD custom SAML connection, read this.

You can upload the ADFS metadata:

The ADFS metadata is at:

https://my-adfs/federationmetadata/2007-06/federationmetadata.xml

After uploading this, you will find the Azure AD metadata here:

On the ADFS side, Azure AD will be a Claims Provider (CP) so import the Azure AD metadata into a new CP.

In terms of claims rules, I just used three pass-through rules:

I had to configure the new Relying Party (RP) manually.

Ensure you tick the SAML 2.0 box.

The identifier is the entityID and the ACS endpoint is the service URL as above.

Remember to add the same three claims rules to the RP.

To test the connectivity, use the “Test” button:

Click “Sign in as current user”. If you get an error because the user is not a member of the application, just click the “Fix It” button. Neat!

Running this, we go to the apps panel:

myapps.microsoft.com

Click the ADFS icon.

Note: This uses the IDP Initiated flow so ensure this is enabled in ADFS.

Set-AdfsProperties –EnableIdpInitiatedSignonPage $True

This will take you to ADFS. ADFS will display all the SAML RP connections in the drop-down Click the correct application.

Note: There is a way to hide this screen. By default if you pass in:

?loginToRp=[ADFS RP identifier]

to the IdpInitiatedSignOn.aspx page, ADFS will look for a relying party based on the parameter. However, it is not possible to add this from Azure AD.

And we are done!

All good!