Si vous ne le saviez pas, le cloud de Microsoft se base sur un système unique en son genre centré autour d’un composant : l’Azure Active Directory. Très similaire à ce que l’on peut retrouver dans un Active Directory classique, celui que l’on appelle plus communément l’Azure AD est la pierre angulaire de la gestion des identités chez la société de Redmond. Cela apporte des avantages, comme par exemple le portage de l’authentification de vos applications ou encore la synchronisation simple d’un AD on-premise vers Azure. Cependant, celle-ci est également un de ses plus gros désavantages puisque jusqu'à récemment, si l’on souhaitait utiliser un fournisseur d'identités tiers déjà existant, ce n’était tout bonnement pas possible.
Dans cet article, nous allons nous concentrer sur External Identities, une nouvelle fonctionnalité permettant de répondre à cette problématique.
En mars dernier, Microsoft a mis à disposition External Identities, un composant faisant partie intégrante de l’Azure Active Directory. Celui-ci a été conçu pour donner la possibilité aux entreprises de fournir un accès à leurs applications et ressources Azure à des personnes extérieures tout en les laissant s’authentifier en utilisant le fournisseur d'identités de leur choix. Ceci permet alors à des distributeurs, partenaires, ou clients d’amener leur propre identité (on emploie alors le terme de “Bring Your Own Identity”) et d’utiliser leurs identifiants pour accéder à vos ressources tout en gardant la mainmise sur les accès donnés à ces personnes.
À ce jour, External Identities supporte plusieurs fournisseurs d'identités :
Pour toute information concernant la configuration de ces différents types de provider, Microsoft met à disposition cette documentation (section “How-to-guides -> Identity Providers”) décrivant de manière succincte les différentes étapes pour mettre en place cette fonctionnalité.
Même si l’ouverture du cloud de Microsoft à d'autres fournisseurs d'identités est réelle, une dépendance à l’Azure Active Directory reste bien présente. En effet, la structuration de l’IAM Azure est centralisée autour de cette brique, ce qui nous oblige à lui rattacher ces identités externes, notamment pour des questions d’affectations de droits. La conséquence directe de cela est la nécessité de créer, pour chaque entité externe, un utilisateur de type “Guest” avec son propre nom de domaine.
Même si l’on pourrait s’attendre à ce que l’opération soit faite automatiquement, cette création manuelle est belle et bien nécessaire pour s’intégrer au modèle Azure.
Lorsque vous avez fait le choix du fournisseur d'identités que vous allez utiliser, il vous faudra configurer la fédération avec Azure. La procédure ainsi que le processus d’authentification diffèrent alors selon le provider sélectionné. Nous allons ici nous concentrer sur la fonctionnalité au travers du protocole SAML.
Pour ce protocole en particulier, voici à quoi ressemble le processus d’authentification :
À noter que le processus d’authentification ne peut s’initier qu’à partir d’Azure et non pas depuis le fournisseur d'identités. En effet, il est nécessaire que celui-ci détecte que vous souhaitez utiliser une identité externe pour ensuite engager la redirection vers votre IDP. On parle alors de connexion Service Provider initiated (vs IDP initiated).
Pour accéder à la configuration relative aux External Identities, rendez-vous sur le portail Azure dans la partie Azure Active Directory, accédez à la tuile correspondante puis sélectionnez “All identity providers”. Vous obtenez ainsi la page de configuration des fournisseurs d'identités :
Cette section résume tous les IDP configurés sur votre tenant. Vous avez ainsi à votre disposition tous les types de fournisseurs énoncés précédemment. Il ne vous reste donc plus qu’à configurer votre fournisseur d'identités et à le renseigner sur cette page. Dans le cadre de cet article, cette partie sera couverte par un cas pratique dans la section suivante.
Histoire de mettre la main à la pâte, nous allons rentrer un peu plus dans le concret avec un cas pratique d’implémentation d’External Identities. Comme énoncé précédemment, nous prenons ici le parti d’utiliser le SAML comme protocole d’authentification. Le fournisseur d'identités que nous allons utiliser sera Keycloak, un composant open source sous la gestion de RedHat.
Afin de simuler la demande d’accès d’un partenaire à nos ressources Azure, nous allons utiliser le domaine mycompany.org comme exemple. L’objectif sera donc d’authentifier les utilisateurs de ce domaine sur notre tenant Azure grâce à External Identities.
Pour ce qui est du déploiement, nous utiliserons Terraform, outil d’Infrastructure as Code très populaire du marché. Si vous ne l’avez pas sur votre poste, vous pouvez dès à présent l’installer à partir de cette page. Tout le code utilisé est disponible dans un dépôt Github. Il vous suffit donc de le récupérer et de l’exécuter si vous souhaitez réaliser cette démonstration en même temps de votre côté.
Avant toute chose, il nous faut bien évidemment un serveur Keycloak à notre disposition. Pour cela, nous allons tout simplement instancier un conteneur Docker (on excusera le mot de passe non sécurisé pour cette démonstration) :
export KEYCLOAK_USER=admin
export KEYCLOAK_PASSWORD=admin
docker run -d --name keycloak -p 8443:8443 -e KEYCLOAK_USER=$KEYCLOAK_USER \
-e KEYCLOAK_PASSWORD=$KEYCLOAK_PASSWORD quay.io/keycloak/keycloak:12.0.4
# Nous allons également configurer localement un domaine customisé pour accéder à notre keycloak
sudo vi /etc/hosts
...
127.0.0.1 keycloak.mycompany.org
Une fois le conteneur déployé, vous pouvez accéder directement à la page d’administration du Keycloak via l’adresse https://keycloak.mycompany.org:8443/auth/admin en renseignant les identifiants définis dans la commande précédente. Si tout se passe bien, vous vous retrouvez connecté en tant qu’administrateur :
Nous allons maintenant préparer Keycloak en créant un realm dédié ainsi que des utilisateurs pour le bon fonctionnement de cette démonstration.
Si l’on regarde dans le dossier setup du dépôt de sources, on retrouve les ressources dans le fichier keycloak.tf (les variables d’entrées sont définies dans le fichier input.tf) :
# Realm Keycloak contenant toute la configuration
resource "keycloak_realm" "realm" {
realm = var.realm_name
enabled = true
}
# Ensemble d'utilisateurs appartenant au realm
resource "keycloak_user" "user_with_initial_password" {
for_each = { for user in var.users : user.username => user }
realm_id = keycloak_realm.realm.id
enabled = true
username = each.value.username
first_name = each.value.first_name
last_name = each.value.last_name
email = each.value.email
# On configure ici le mot de passe d'une manière très simple pour la démonstration
initial_password {
value = "password"
temporary = false
}
}
Pour créer ces ressources, lancez les commandes suivantes (faites bien attention à avoir configuré les variables d’environnement KEYCLOAK_USER et KEYCLOAK_PASSWORD car elles sont utilisées par le provider Terraform pour s’authentifier auprès du Keycloak) :
cd setup
# Initialiser la configuration Terraform
terraform init
# Établir un plan des changements effectués si la configuration est appliquée
terraform plan
# Appliquer la configuration Terraform (une confirmation vous sera demandée)
terraform apply
Lorsque l’exécution est terminée, on peut constater que le realm ainsi que les utilisateurs sont créés :
Passons maintenant à la configuration de l’authentification SAML qui permettra à nos utilisateurs externes de se connecter au tenant Azure. Pour mettre cela en place côté Keycloak, il est nécessaire de créer un client SAML. Le code Terraform permettant de le déployer est disponible dans le dossier saml du dépôt Git.
locals {
azure_tenant_login_url = "https://login.microsoftonline.com/${var.tenant_id}/saml2/"
}
# Client utilisé pour l’authentification SAML auprès d’Azure
resource "keycloak_saml_client" "saml_client" {
realm_id = data.keycloak_realm.realm.id
client_id = "urn:federation:MicrosoftOnline"
name = "azure-idp-saml"
description = "SAML client to federate access on an Azure tenant"
base_url = "/auth/realms/${data.keycloak_realm.realm.id}/protocol/saml/clients/${local.saml_client_name}"
valid_redirect_uris = [local.azure_tenant_login_url]
name_id_format = "email"
assertion_consumer_post_url = local.azure_tenant_login_url
sign_documents = true
sign_assertions = true
signature_algorithm = "RSA_SHA1"
client_signature_required = false
include_authn_statement = true
front_channel_logout = true
}
# Mapper SAML pour inclue l’adresse email de l’utilisateur dans les documents SAML
resource "keycloak_saml_user_attribute_protocol_mapper" "saml_email_mapper" {
realm_id = data.keycloak_realm.realm.id
client_id = keycloak_saml_client.saml_client.id
name = "email"
user_attribute = "email"
saml_attribute_name = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
saml_attribute_name_format = "Basic"
}
Quelques remarques concernant ce code Terraform :
Il est également possible qu’une problématique supplémentaire se présente à vous. En effet, une des limitations de la mise en place de Direct Federation est qu’il n’est pas possible de configurer un domaine déjà revendiqué par un Azure Active Directory. Dans certains cas spécifiques, vous pouvez donc vous retrouver dans l’impossibilité de spécifier le domaine de vos utilisateurs externes.
Afin de pallier cela, il est possible de créer un script protocol mapper au niveau du client SAML Keycloak :
resource "keycloak_saml_script_protocol_mapper" "saml_script_mapper" {
realm_id = data.keycloak_realm.realm.id
client_id = keycloak_saml_client.saml_client.id
name = "email"
saml_attribute_name = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
saml_attribute_name_format = "Basic"
script = <<-EOT
var new_domain = '${var.domain_name}';
var username = user.email.substring(0, user.email.lastIndexOf("@"));
var new_email = username + '@' + new_domain;
exports = new_email;
EOT
}
Ce script protocol mapper va, pour chaque processus d’authentification, remplacer le domaine de l’adresse mail de l’utilisateur Keycloak par le domaine de votre choix configuré dans External Identities, ce qui évite d’avoir à modifier la base d’utilisateurs Keycloak. À noter que si vous utilisez ce mapper, veillez à commenter le précédent pour éviter d’avoir un conflit au moment de leur création.
N.B : l’utilisation de ce script protocol mapper oblige l’utilisateur à mentionner l’adresse mail avec le domaine cible au moment de l’authentification sur le portail Azure.
Le processus de déploiement de ces ressources est similaire au précédent. La seule différence est la nécessité de fournir une variable d’entrée tenant_id correspondant à l’ID de votre tenant Azure :
export TENANT_ID=...
cd saml
terraform init
terraform plan -var tenant_id=$TENANT_ID
terraform apply -var tenant_id=$TENANT_ID
Une fois le code Terraform exécuté, on retrouve alors le client SAML créé et configuré :
Nous avons maintenant toutes les ressources nécessaires côté Keycloak pour authentifier nos utilisateurs. Il ne reste plus qu’à configurer le pendant Azure pour obtenir le processus d’authentification complet.
Côté Azure, plusieurs éléments sont nécessaires. Tout d’abord, nous allons configurer le tenant pour pouvoir identifier les utilisateurs provenant de notre Keycloak. Pour cela, rendons-nous dans la tuile de configuration d’External Identities (le moyen d’y parvenir est décrit plus tôt dans la deuxième section de cet article). Ensuite, ajoutons notre Keycloak en tant que provider SAML en cliquant sur “New SAML/WS-Fed IDP”. On obtient alors le formulaire suivant :
Les informations à fournir sont les suivantes :
Ensuite, une fois External Identities configuré, il ne reste plus qu’à créer les utilisateurs invités. Comme mentionné au début de cet article, ceci est nécessaire pour qu’Azure autorise l’authentification d’utilisateurs externes. Toutefois, on peut remarquer qu’il n’est pas nécessaire d’accepter l’invitation pour que l’utilisateur puisse se connecter, cela fonctionne directement.
Contrairement aux parties précédentes, nous allons effectuer leur création manuellement drepuis le portail par souci de simplicité. En effet, au moment de l’écriture de cet article, il n’existe pas de ressource Terraform pour inviter un utilisateur. Des travaux sont en cours pour créer cette ressource dans le provider AzureAD afin de la rendre disponible dans une future version.
À noter qu’il est possible dans l’état actuel de le faire fonctionner via Terraform en utilisant l’API Graph HTTP avec des null_resource et le provisioner local-exec mais l’implémentation reste complexe et non optimale, ce qui est loin d’être idéal et surtout non nécessaire dans le cadre de cet article.
Pour inviter des utilisateurs via le portail Azure, il faut se rendre dans la tuile "Users" de l’Azure Active Directory puis cliquer sur “New Guest user”. Il suffit alors de renseigner l’adresse mail de l’utilisateur externe pour envoyer une invitation. Dans le contexte de notre démonstration nous allons inviter nos deux utilisateurs, aaliceberg@mycompany.org et bbobson@mycompany.org.
Une fois les utilisateurs invités, nous disposons de tous les éléments pour autoriser l’authentification d’utilisateurs externes à notre tenant Azure. Nous pouvons dès à présent tester le processus de connexion décrit précédemment :
Et voilà ! Nous sommes bien identifiés sur notre tenant Azure en utilisant le compte aaliceberg@mycompany.org de notre partenaire fictif. Il nous suffit maintenant de gérer l’utilisateur invité correspondant à cet utilisateur comme n’importe quel autre. Vous êtes donc libre de lui donner les droits d’accès aux ressources que vous souhaitez, l’ajouter à un groupe existant, etc.
N.B : la session Azure de l’utilisateur externe est liée à celle sur le fournisseur d'identités externe ce qui signifie que si vous vous déconnectez sur Azure, la session de l’IDP se fermera également, et inversement.
Nous venons de voir que grâce à External Identities, il est maintenant possible de se passer, même partiellement, d’Azure Active Directory pour authentifier des utilisateurs sur le cloud de Microsoft. Cette fonctionnalité va permettre à de nombreuses entreprises possédant déjà un fournisseur d'identités d’accéder à des ressources Azure tout en conservant les mêmes identifiants. En plus de cela, la multitude de choix dans le type de fournisseur d'identités amène une vraie flexibilité et s’adapte à de nombreux cas d’usage.
Même si cela apporte des avantages d’un point de vue fonctionnel, il est également important de prendre connaissance de certaines limitations, notamment dues à la disponibilité récente de la fonctionnalité :
En mettant à disposition cette fonctionnalité, Microsoft ouvre une porte à la venue de nouvelles entreprises en levant un des points bloquants de la gestion des identités sur Azure. External Identities vient alors en complément d’autres composants comme Azure Lighthouse qui favorise la gestion de ressources dans un contexte multi-tenant. La synchronisation d’Azure AD avec le protocole standardisé SCIM peut également être une option si votre fournisseur d'identités le permet.