Azure AD Federation with Keycloak as SAML identity provider using external B2B guest users - Using a different email domain in Azure AD and Keycloak

24.05.2023 | Eike Waldt in howto

Recap of Post 1

Post 1 showed you to set up Keycloak, your DNS, an Azure External Identity Provider and how to invite internal B2B guest users.

Recap of Post 2

Post 2 showcased keycloak_to_azure.py, a way to automate user and group sync from Keycloak to Azure AD utilizing Microsoft Graphs REST API via HTTP and the python-keycloak package.

Using a different email domain in Azure AD and Keycloak

Here at B1 Systems, we had the challenge of already existing Azure AD users. They used our main email domain as their UPN suffix and the domain is a custom DNS verified domain. These “verified domains” cannot be used with SAML-Fed IdP federation, so we have to set up the federation with an “unverified domain”.

Example Setup with a hitch

Your ACME company owns acme.com and uses it for all its main activities, e.g. hosting your website and sending/receiving your mail. acme.com is registered as a custom DNS verified domain in Azure AD. You have your admin users inside this domain (and you don’t want to change that). You are also using this domain for users and their email addresses inside your Keycloak. Keycloak is your one and only Identity and Access Management. Remember: The user’s domain part is the criterion for the user federation to Keycloak. Again, the acme.com domain cannot be used with SAML-Fed IdP federation, as it is a “verified domain”. To work around this, you are now using acme.corp (also owned by your company) as the domain for your staff’s users and establish an IdP federation for this very domain inside Azure AD (see Post 1).

Problem as seen in the login process

When you now login to your Azure tenant by visiting https://portal.azure.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/ you will be forwarded to your Keycloak instance and presented with a login window, as usual. After a successful login, you will be presented with an Azure error message resembling something like “user cannot be found”. If you analyze the login process with a tool like SAML-tracer, you would see that the needed SAML Attribute http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress sadly is a user from the acme.com domain. This is of course “correct”, as the user entry in Keycloak includes the email attribute from our main email domain acme.com.

How to solve this …

We would need a different answer from Keycloak for the email attribute. The answer has to include our SAML-federated domain acme.corp and not the real acme.com domain.

  • A simple solution would be to add an additional attribute, e.g. email_azure to every user and just using this in the “User Attribute Mapper” from Post 1.
    • This would have to be maintained/automated somehow.
  • If you’re using LDAP integration inside Keycloak, this could even be added as an LDAP attribute.
    • This would have to be maintained/automated somehow.
  • Can we just “overwrite” this inside Keycloak?

Overwrite email attribute in Keycloak

Keycloak <= v16 (old WildFly Distribution) -> you should not run this anymore

Keycloak <= v16 had a “Javascript Mapper” which could be used to achieve hacks like this pretty easy:

  • Client -> Client scopes -> *-dedicated -> Mappers -> Add mapper -> By Configuration -> javascript Mapper:
protocol: saml
name: email_com
Mapper Type: javascript Mapper
Script:
  input = user.email;
  username = input.split("@")[0];
  domain = input.split("@")[1];
  output = username + "@acme.corp";
Single Value Attribute: ON
Friendly Name: email_com
SAML Attribute Name: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
SAML Attribute NameFormat: URI Reference

Keycloak >= v17 (Quarkus Distribution)

Keycloak v17 introduced Quarkus as the new default distribution and got rid of old clutter like the “Javascript Mapper”.

Overwriting the email attribute is a bit more challenging here.

keycloak-custom-email-domain-mapper

One approach could be to use or write a custom provider using the Service Provider Interface (SPI) or to be more precise, a custom protocol mapper that changes our email attribute.

The code

mschwartau/keycloak-custom-protocol-mapper-example is a great starting point of achieving this and similar goals. Kudos!

I forked mschwartau’s repo and created yeoldegrove/keycloak-custom-email-domain-mapper for the sole purpose of rewriting the email user attribute and using it as the http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress SAML attribute.

Explaining the whole mapper would be “too much” and a bit boring I guess. So let’s just quickly explain how to use it. If you’re interested in the boring details, it is open source ;)

Installing the Mapper

You have to ship the *.jar file (containing the mapper), which can be build by running mvn clean package, to your Keycloak instance. Custom providers can just be placed inside /opt/keycloak/providers and will be automatically loaded during startup. If you are using a containerized setup, the easiest way would be to just use the provided Dockerfile and spinning up the container with command: start (or adapting the CMD line iside the Dockerfile). Also have a look at Running Keycloak in a container for more details on how you can adapt the image.

To check that the provider is loaded, have a look at e.g. Provider info - https://auth.acme.com/auth/admin/acme/console/#/acme/providers and look for saml-custom-email-domain-mapper.

Using the Mapper

After you have added saml-custom-email-domain-mapper to your Keycloak instance, you can use it like any other mapper.

  • Client -> Client scopes -> *-dedicated -> Mappers -> Add mapper -> By Configuration -> Custom Email Domain Mapper:

Be sure to set acme.corp as Email Domain.

protocol: saml
Mapper Type: Custom Email Domain Mapper
Name: email
Email Domain: acme.corp
SAML Attribute Statement: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
SAML Attribute NameFormat: urn:oasis:names:tc:SAML:2.0:attrname-format:uri

Recap and Conclusion - A working setup with different email domains in Azure AD and Keycloak

After following all the steps above, let’s shortly recap what your setup now looks like:

  • acme.com is registered as a custom DNS verified domain in Azure AD
  • acme.com domain cannot be used with SAML-Fed IdP federation, as it is a “verified domain”.
    • you have set up IdP-federation for acme.corp
  • acme.corp is used to login to the Azure portal
    • you are forwarded to Keycloak due to IdP-federation for acme.corp
    • Keycloak answers with an email user attribute that includes acme.com
      • saml-custom-email-domain-mapper overwrites the email attribute and adds the http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress SAML attribute to the acme.corp domain
  • Azure AD accepts the acme.corp SAML answer and your users can login successfully now.

Congratulations! You’re now using different email domains in Azure AD and Keycloak and the login is working.

Next Steps

This is where our 3-part Azure and Keycloak series comes to an end. If your’re interested in a similar setup or even want a B1 Consultant to set it up four you, feel free to reach out. We’re glad to help you.

Eike Waldt
Eike Waldt
Eike Waldt is a Linux Consultant and Trainer and has been with B1 Systems since 2015. During his career he has worked in many SAP and SUSE focused projects. This included designing complex mechanisms for maintaining large landscapes and approaches to maintain and refactor their codebase via continious integration (CI) solutions. Some of his favority technologies and topics are high availibilty clusters (pacemaker/corosync) and Infrastructure as Code (e.g. Terraform, Ansible, Salt, Chef). Apart from wagework, he is an advocate of community supported agriculture (CSA, please look it up), which (who would have thought that) also includes running and designing IT infrastructure.

 


Haben Sie Anmerkungen oder Nachfragen? Melden Sie sich unter blog%b1-systems.de
Col 2