Les parcours d'authentification et le MFA
Flux d'authentification, sous-flux conditionnels, required actions, facteurs disponibles, niveaux d'authentification (ACR, LoA) et step-up, protections du mot de passe, et ce que demanderait un MFA adaptatif.
Sur cette page
Le MFA est rarement un interrupteur unique. Dans une architecture réelle, il varie selon la population, l’application et l’opération demandée, et il faut organiser son activation pour des comptes qui n’ont encore aucun facteur. Keycloak exprime tout cela avec des flux d’authentification composés de briques. Ce cours montre ce que ces briques permettent nativement, où commencent les extensions, et comment construire une offre de MFA par paliers. Les notions de facteur et de niveau d’assurance sont supposées connues (voir les fondations).
Anatomie d’un flux d’authentification
Un flux est une suite d’exécutions (authenticators) et de sous-flux. Chaque élément a une exigence :
- Required : doit réussir ;
- Alternative : au moins un des éléments alternatifs du niveau doit réussir ;
- Disabled : ignoré ;
- Conditional (sous-flux seulement) : exécuté si toutes ses conditions sont vraies.
Les flux sont liés au realm pour chaque usage : navigateur (browser flow), inscription, réinitialisation des credentials, direct grant, authentification des clients, first broker login. Un client peut surcharger les liaisons browser et direct grant (voir le cours 2).
Le flux browser par défaut de Keycloak 26.4 se lit ainsi :
browser
├── Cookie Alternative
├── Kerberos Disabled
├── Identity Provider Redirector Alternative
├── Organization Alternative
│ └── Browser - Conditional Organization Conditional
└── forms Alternative
├── Username Password Form Required
└── Browser - Conditional 2FA Conditional
├── Condition - user configured Required
├── Condition - credential Required
├── OTP Form Alternative
├── WebAuthn Authenticator Disabled
└── Recovery Authentication Code Form Disabled
Par défaut, le second facteur n’est donc demandé qu’aux utilisateurs qui en ont configuré un, et pas à ceux qui viennent de se connecter avec une passkey. Le MFA est optionnel tant qu’on ne change rien.
Les sous-flux conditionnels
Les conditions disponibles nativement en 26.4 :
| Condition | Vraie si… | Usage typique |
|---|---|---|
| Condition - user configured | l’utilisateur a configuré les authenticators du sous-flux | MFA facultatif, activé par l’usager |
| Condition - user role | l’utilisateur a le rôle indiqué (de realm ou de client) | MFA imposé à une population |
| Condition - user attribute | un attribut a la valeur attendue (option : attributs des groupes, négation) | MFA selon un niveau de sensibilité porté par le compte |
| Condition - client scope | le client a le scope en default, ou l’a demandé en optional | MFA déclenché par l’application |
| Condition - sub-flow executed | un sous-flux précédent a (ou n’a pas) réussi | refuser l’accès si aucun second facteur n’a été joué |
| Condition - credential | un type de credential a (ou n’a pas) été utilisé | ne pas redemander de facteur après une passkey |
| Condition - Level of Authentication | le niveau demandé correspond | step-up (voir plus bas) |
S’y ajoutent deux authenticators utiles dans ces sous-flux : Deny access (avec un message) et Allow access. Exemple de politique « MFA obligatoire pour tous, enrôlement forcé » : après le sous-flux 2FA, un sous-flux conditionnel avec Condition - sub-flow executed (non exécuté) puis OTP Form en Required.
Les required actions
Une required action est une étape que l’usager doit accomplir avant d’accéder à l’application. Keycloak 26.4 fournit notamment : Verify Email, Update Password, Update Profile, Verify Profile, Configure OTP, Webauthn Register, Webauthn Register Passwordless, Recovery Authentication Codes, Update Email, Terms and Conditions, Delete Account, Update User Locale.
Elles se déclenchent de trois façons :
- par l’administrateur, sur un compte ou en masse (après une reprise : Update Password, Configure OTP) ;
- par défaut pour tout nouveau compte (option Default action) ;
- par l’application, avec le paramètre
kc_action(Application Initiated Action), par exemplekc_action=CONFIGURE_TOTPdepuis une page « Sécuriser mon compte ».
kcadm.sh update users/$USER_ID -r academy -s 'requiredActions=["VERIFY_EMAIL","CONFIGURE_TOTP"]'
Le parcours de migration d’une population vers le MFA se construit avec ces briques : annonce, période où l’enrôlement est proposé (kc_action ou required action), puis bascule où le facteur devient obligatoire (condition sur un rôle ou un attribut posé par lot).
Les facteurs disponibles
| Facteur | Natif en 26 | Remarques |
|---|---|---|
| TOTP / HOTP | oui | Politique OTP par realm (algorithme, chiffres, période), applications compatibles listées dans la console |
| WebAuthn en second facteur (clé FIDO2) | oui | Politique WebAuthn dédiée (attestation, vérification de l’utilisateur) |
| Passkeys (connexion sans mot de passe) | oui, supporté depuis 26.4 | Intégré aux formulaires de connexion (conditional UI et modal UI), politique WebAuthn Passwordless |
| Codes de récupération | oui, supporté depuis 26.3 | Alternative en cas de perte du facteur, protégée par la détection de force brute |
| Code par e-mail | non documenté | Extension, ou catalogue de l’hébergeur à vérifier |
| Code par SMS | non | Extension ; déconseillé comme facteur fort par les référentiels de sécurité |
| Certificat X.509, carte à puce | oui | Authenticator X.509 ; dépend de la terminaison TLS en amont |
| Kerberos / SPNEGO | oui | Utile pour le poste de travail d’un domaine Active Directory |
Pour une architecture de service public, les recommandations de l’ANSSI sur l’authentification multifacteur sont le référentiel pour classer ces facteurs par robustesse.
MFA différencié : ACR, LoA et step-up
Keycloak raisonne en niveaux d’authentification (LoA, des entiers) et expose aux applications des valeurs ACR (chaînes). On déclare la correspondance dans les réglages généraux du realm (recommandé) ou sur un client :
kcadm.sh update realms/academy -s 'attributes."acr.loa.map"="{\"standard\":1,\"renforce\":2}"'
Le flux browser contient alors un sous-flux conditionnel par niveau, chacun avec Condition - Level of Authentication (niveau, et Max Age : durée pendant laquelle ce niveau reste acquis dans la session). Les niveaux sont ordonnés du plus faible au plus fort, et chaque niveau inclut les facteurs du précédent.
L’application demande un niveau avec acr_values=renforce (non essentiel) ou avec le paramètre claims en marquant acr comme essentiel. Si l’utilisateur a déjà une session de niveau 1, Keycloak ne lui demande que le facteur manquant : c’est le step-up. Le claim acr, ajouté par le client scope acr présent par défaut, indique le niveau atteint. Dans l’exemple ci-dessous, on suppose qu’il reprend la valeur ACR demandée ; sans demande explicite, il contient le numéro du niveau (1, ou 0 si le niveau a expiré et que seule la session SSO a servi) :
{
"iss": "http://localhost:8080/realms/academy",
"azp": "portail-sensible",
"acr": "renforce",
"auth_time": 1793876110
}
Côté client, trois réglages complètent le dispositif :
| Réglage du client | Effet | À savoir |
|---|---|---|
| ACR to LoA mapping | correspondance propre au client | à éviter sauf nécessité, préférer celle du realm |
| Default ACR values | niveau demandé si l’application n’en demande aucun | l’application peut demander moins : ce n’est pas une garantie |
| Minimum ACR value (26.1) | niveau imposé par Keycloak quelle que soit la demande | le moyen d’appliquer un palier à une application qui ne vérifie pas acr |
Le step-up par conditions de niveau suppose des niveaux emboîtés. Si un niveau exige un facteur différent (et non additionnel), la documentation oriente vers les client policies, qui sélectionnent un flux complet selon l’ACR demandé ou d’autres conditions (depuis 26.2). Le step-up existe aussi pour SAML via un mapping ACR vers URI : en préversion en 26.6, puis annoncé pour les clients SAML en 26.7, à vérifier selon la version déployée.
C’est la base d’une offre de service par paliers : palier 1 mot de passe, palier 2 mot de passe et OTP ou WebAuthn, palier 3 passkey ou clé matérielle seule, chaque application étant rattachée à un palier par son Minimum ACR value.
Mots de passe, force brute et sessions
Politique de mots de passe (par realm) : longueur, classes de caractères, différent du nom d’utilisateur et de l’e-mail, historique, expiration, liste de mots interdits, expression régulière, algorithme et itérations de hachage, âge maximal d’authentification avant changement. Une nouvelle politique ne s’applique pas aux mots de passe existants avant leur prochain changement.
Protection contre la force brute : désactivée par défaut. Elle s’applique au mot de passe, à l’OTP et aux codes de récupération. Deux modes : verrouillage temporaire (attente qui croît avec les échecs, plafonnée) ou permanent (jusqu’à déblocage par un administrateur), ainsi qu’un mode mixte : verrouillage permanent après un nombre donné de verrouillages temporaires. Le message affiché reste « identifiant ou mot de passe invalide » pour ne rien révéler. Depuis 26.8, les compteurs d’échec sont stockés en base par défaut et survivent aux redémarrages.
kcadm.sh update realms/academy -s bruteForceProtected=true -s permanentLockout=false \
-s failureFactor=5 -s waitIncrementSeconds=60 -s maxFailureWaitSeconds=900
Sessions : SSO Session Idle (30 minutes par défaut) et SSO Session Max (10 heures) au niveau du realm, Remember me avec ses propres durées, sessions hors ligne pour les refresh tokens longs. Un client peut raccourcir ses propres durées sans dépasser celles du realm.
Le MFA adaptatif : ce qui manque
Keycloak n’a pas de moteur de risque. Il ne calcule pas de score à partir de l’adresse IP, de l’appareil, de la géolocalisation ou du comportement. Ce qu’il offre nativement :
- des conditions statiques (rôle, attribut, client, facteur utilisé, niveau) ;
- l’authenticator historique Conditional OTP Form, encore présent en 26.4, qui peut forcer ou sauter l’OTP selon un rôle ou un en-tête HTTP posé par un équipement amont ;
- les événements de connexion, exploitables a posteriori par un SIEM (cours 9).
Un MFA adaptatif demande donc une extension : une condition ou un authenticator qui évalue un contexte (plage d’adresses, cookie d’appareil connu, heure, pays) ou qui interroge un moteur de risque externe, puis déclenche un sous-flux renforcé. Il faut aussi stocker l’historique des appareils et prévoir l’explicabilité des refus pour le support. Présentez-le comme un chantier à part entière, pas comme une option à cocher.
Imposer l'OTP à une population et tester la force brute
30 min
Installer le lab- Depuis
keycloak-academy-lab/, préparez kcadm et deux comptes dans le realmacademy, dont un portant le rôlemfa-requis.
kcadm() { docker compose exec -T keycloak /opt/keycloak/bin/kcadm.sh "$@"; }
kcadm config credentials --server http://localhost:8080 --realm master --user admin --password admin
kcadm create realms -s realm=academy -s enabled=true
kcadm create roles -r academy -s name=mfa-requis
for U in agent-mfa agent-simple; do
kcadm create users -r academy -s username=$U -s email=$U@example.org \
-s firstName=Agent -s lastName=$U -s enabled=true -s emailVerified=true
kcadm set-password -r academy --username $U --new-password 'Academy2026!'
done
kcadm add-roles -r academy --uusername agent-mfa --rolename mfa-requis- Dupliquez le flux browser et listez les exécutions de la copie.
kcadm create authentication/flows/browser/copy -r academy -s newName=navigateur-mfa
kcadm get authentication/flows/navigateur-mfa/executions -r academy --fields displayName,requirement,level- Dans la console (realm
academy, Authentication, fluxnavigateur-mfa), dans le sous-fluxnavigateur-mfa Browser - Conditional 2FA: passez Condition - user configured à Disabled, ajoutez la condition Condition - user role en Required, configurez-la avec le rôlemfa-requis(icône engrenage), puis passez OTP Form à Required. - Liez le flux comme flux navigateur du realm (menu Action, Bind flow, Browser flow), ou en ligne de commande :
kcadm update realms/academy -s browserFlow=navigateur-mfa- Dans une fenêtre privée, connectez-vous à http://localhost:8080/realms/academy/account avec
agent-mfa. Keycloak impose l’enrôlement OTP : scannez le QR code avec une application TOTP, ou cliquez sur le lien pour afficher la clé et générez un code avecoathtool --totp -b CLEsi l’outil est installé. - Dans une autre fenêtre privée, connectez-vous avec
agent-simple: aucun second facteur n’est demandé. - Retirez le rôle à
agent-mfa, puis reconnectez-vous : l’OTP n’est plus demandé, même s’il est configuré. La condition porte sur le rôle, pas sur le facteur. Remettez le rôle ensuite.
kcadm remove-roles -r academy --uusername agent-mfa --rolename mfa-requis- Activez la protection contre la force brute avec un seuil bas, puis échouez trois fois à la connexion de
agent-simple. Le message reste identique à une erreur de mot de passe, même une fois le compte verrouillé.
kcadm update realms/academy -s bruteForceProtected=true -s failureFactor=3- Consultez l’état du compte, puis débloquez-le.
ID=$(kcadm get users -r academy -q username=agent-simple --fields id --format csv --noquotes)
kcadm get attack-detection/brute-force/users/$ID -r academy
kcadm delete attack-detection/brute-force/users/$ID -r academy- Pour aller plus loin, ajoutez dans Realm settings la correspondance ACR
standardvers 1 etrenforcevers 2, et esquissez sur papier le flux à deux niveaux décrit dans la section step-up, avec le Max Age de chaque niveau.
Natif, extension ou hébergeur
Natif : fourni par Keycloak, à configurer. Extension : demande du code à maintenir (un SPI, le mécanisme de plugin de Keycloak). Hébergeur : dépend de la plateforme qui héberge Keycloak, à vérifier avec elle.
| Capacité | Verdict | Précision |
|---|---|---|
| Flux d'authentification et sous-flux conditionnels (rôle, attribut, facteur configuré, client scope, credential utilisé, niveau) | Natif | Composés dans la console ; les conditions sous-flux exécuté et client scope existent depuis 26.1, la condition credential depuis 26.4. |
| TOTP, WebAuthn (clés FIDO2), passkeys, codes de récupération | Natif | Passkeys supportés depuis 26.4, codes de récupération supportés depuis 26.3. |
| Code à usage unique envoyé par e-mail ou SMS | Extension | Aucun authenticator de ce type n'est documenté dans le guide d'administration 26. Extension communautaire, maison, ou catalogue de l'hébergeur. |
| Facteurs supplémentaires proposés par l'hébergeur | Hébergeur | Vérifier avec l'hébergeur quelles extensions d'authentification il fournit et maintient. |
| Niveaux d'authentification (ACR vers LoA) et step-up | Natif | Correspondance ACR vers LoA par realm ou par client, ACR par défaut et ACR minimal par client (26.1). |
| Politique de mots de passe, protection contre la force brute, durées de session | Natif | Réglées par realm ; les durées de session peuvent être raccourcies par client. |
| MFA adaptatif fondé sur un score de risque (adresse IP, appareil, géolocalisation, comportement) | Extension | Aucun moteur de risque natif. Il faut un authenticator ou une condition spécifique, éventuellement relié à un moteur externe. |
Vérifier ce que vous avez retenu
5 questions
-
Vous voulez imposer l'OTP aux agents qui ont le rôle « gestionnaire », y compris s'ils ne l'ont pas encore configuré. Quel montage convient ?
Condition - user configured n'est vraie que si l'utilisateur a déjà un OTP : l'OTP resterait facultatif. La condition sur le rôle déclenche l'OTP Form, qui fait enrôler l'utilisateur s'il n'a pas encore de facteur.
-
Une application sensible demande acr_values=renforce, mais un utilisateur malveillant retire ce paramètre de l'URL. Que doit faire l'architecture ?
Les paramètres passent par le navigateur et peuvent être modifiés. Le Minimum ACR value impose le niveau côté Keycloak, et la vérification du claim acr par l'application ferme la porte (PAR ou request object aident aussi).
-
Le niveau 1 (mot de passe) a un Max Age de 36 000 secondes et le niveau 2 (OTP) un Max Age de 0. Que se passe-t-il quand l'application redemande le niveau 2 dix minutes plus tard ?
Le niveau 1 est encore valide grâce à son Max Age ; le niveau 2, avec un Max Age de 0, ne vaut que pour l'authentification en cours et doit être rejoué.
-
Un comité demande un « MFA adaptatif comme chez les grands fournisseurs cloud ». Quelle réponse est juste pour Keycloak 26 ?
Les conditions natives permettent un MFA différencié par population et par application. L'évaluation du risque (réseau, appareil, comportement) n'existe pas nativement et se construit par extension.
-
Pourquoi un verrouillage permanent après 5 échecs est-il souvent un mauvais choix pour un portail grand public ?
Le verrouillage permanent transforme la protection en déni de service ciblé. Un verrouillage temporaire progressif, combiné au MFA, protège sans offrir ce levier.
Pour aller plus loin
- Server Administration Guide — Authentication flows
- Server Administration Guide — Conditions in conditional flows
- Server Administration Guide — Creating a browser login flow with step-up mechanism
- Server Administration Guide — Password guess: brute force attacks
- OpenID Connect Core 1.0 — paramètres acr_values et claims