Out in the interwebs there are 100s of guides to use Microsoft Azure Directory (Azure AD) as an identify provider (IdP) in keycloak. But we want it to be the other way around! Keycloak shall be a SAML federated IdP for Azure AD.
There is official and proper Microsoft documentation available and I advise you to at least skim through it and refer to it in case you face any issues. Of course it does not include details on how to add “3rd party” solutions like keycloak 😉 But it includes all parameters that we need.
Our setup and the login process in a nutshell
Our keycloak instance has a user federation with our OpenLDAP server. This guide should also work if you maintain your users in keycloak itself.
If a user logs into the azure tenant which is federated with keycloak (via SAML), the user is forwarded to our keycloak instance for the login process. The criterion for a user to be federated is the domain part of the users’ email address. Keycloak sends the SAML Response to Azure AD and the user is logged in.
One thing to notice is that an Azure AD internal B2B guest user (or a normal guest user) needs to exist, prior to logging in. Creating these users is a manual process, but can of course be automated.
Also, no roles or group permissions are usually passed from keycloak to Azure AD. There needs to be some kind of automation to achieve this (another blog post).
Implementation
Keycloak
Keycloak v21 is used in this guide. Older Versions will also work but the settings might be called slightly different or found in different places.
Import Client into your realm
- XML is referenced in Example: Configure SAML/WS-Fed based identity provider federation with AD FS
- XML URL
change client settings
Settings -> Client ID
has to match azure tenant URL (or you fiddle with the Audience)- e.g.
https://portal.azure.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/
- e.g.
Keys -> Client Signature Required
needs to beOff
Settings -> Name ID Format
shall be set topersistent
according to Microsoft documentation. We have to set it tousername
aspersistent
would mean altering the user object in keycloak which is read-only in our setup because it is coming from LDAP.- Notice: This changes behaviour of the user representation in Azure AD. Be sure you double check this.
Settings -> Valid redirect URIs
andSettings -> Master SAML Processing URL
have to behttps://login.microsoftonline.com/login.srf
Client scopes -> dedicated -> Scope -> Full scope allowed
needs to beOff
, so that roles aren’t passed to Azure AD (we cannot use them there, so we don’t need them).- Create a new mapper which maps the email address to the required SAML attribute from the Microsoft documentation
Client -> Client scopes -> *-dedicated -> Mappers -> Add mapper -> By Configuration -> User Attribute
:
Name: email
User Attribute: email
Friendly Name: Email Address
SAML Attribute Name: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
SAML Attribute NameFormat: URI Reference
Aggretate attribute values: Off
DNS
For the SAML federation in Azure AD you might need to add a special DNS record. More information can be found in the Microsoft Documentation
e.g. b1-systems.de. TXT DiretFedAuthUrl=https://keycloak.b1-systems.de/realms/b1systems/protocol/saml
Azure AD
We will create a new IdP federation for keycloak. We use the domain “b1-systems.de”, so every login to our azure tenant with an email address inside this domain will be forwarded to keycloak for authentication.
- open Azure Active Directory
- open External Identities – All identity providers
- New SAML/WS-Fed IdP
- Download the metadata file from your keycloak saml descriptor url, e.g. https://keycloak.b1-systems.de/auth/realms/b1systems/protocol/saml/descriptor and upload it.
- Notice: Be sure to fill “Metadata URL” to e.g. automatially renew certificated
Display name: b1-systems.de Identity provider protocol: SAML Domain name for federating IdP: b1-systems.de Select a method for populating metadata: Parse metadata file Metadata file: upload Issuer URI: auto fill Certificate: auto fill Metadata URL: https://keycloak.b1-systems.de/auth/realms/b1systems/protocol/saml/descriptor
- Download the metadata file from your keycloak saml descriptor url, e.g. https://keycloak.b1-systems.de/auth/realms/b1systems/protocol/saml/descriptor and upload it.
- New SAML/WS-Fed IdP
Azure AD Users
As said above, no user information other than the email address is passed from keycloak to Azure AD. No additional SAML claims/attributes are used or at least not documented in the official documentation. This means, that we have to provision the Azure AD internal B2B guest user (or a normal guest user) and also the groups ourselves.
This is fairly simple in the Azure Portal. Just go to Users and add a New User -> Invite external user
. Add the email address and be sure Invite user
is set. Click Invite
and you’re done. The user now receives an email to accept the invite. Nevertheless a login is also possible now without even accepting the invite 😉
If an external user is created, you can add permissions via groups, roles and role assignments as usual in Azure AD.
Test Login
If you configured everything correctly, you can login to your Azure tenant using your tenant URL, e.g. https://portal.azure.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/
Next steps
Microsoft provides PowerShell packages to interact with the Microsoft Graphs REST API and you can also interact with the Microsoft Graphs REST API via HTTP. This enables us to automate the Azure AD user provisioning. A detailed blog entry with some examples might follow 😉