Le précédent article dédié à Keycloak nous a permis de décrire l’utilisation de TOTP en tant que second facteur d’authentification. Cette utilisation de TOTP est principalement mise en œuvre côté Keycloak : une application délègue à Keycloak l’authentification d’un utilisateur, Keycloak met en œuvre les moyens prédéfinis dans sa configuration pour authentifier cet utilisateur via l’utilisation d’un ou plusieurs facteurs authentifiant.

Dans cet article, nous allons aborder une autre manière d’utiliser l’authentification multifacteur, cette fois-ci à l’initiative de l’application.

# Deux mots sur le Step-Up Authentication

Commençons par un cas concret de l’utilisation du Step Up : une boutique en ligne.

Une application web d’achat de biens ou de services en ligne demande relativement tôt à un utilisateur de s’authentifier, la plupart du temps dans le but de lui proposer des réductions ou des recommandations personnalisées. Il s’agit d’une demande d’authentification classique, celle-ci est déléguée à Keycloak. Keycloak réalise alors simplement une authentification avec un unique facteur d’authentification, à savoir identifiant et mot de passe.

Au moment de passer à l’étape du paiement, la boutique souhaite alors valider avec plus de certitude l’authentification de l’utilisateur dans le but de garantir que l’accès et la gestion des informations bancaires soient faites par la bonne personne. La boutique va alors demander à Keycloak une preuve supplémentaire d’authentification de la personne, ce qui se traduit dans Keycloak par le passage par un second facteur d’authentification (comme TOTP par exemple).

Un autre exemple classique de Step-Up est celui de l’application métier qui nécessite une authentification simple pour y accéder, mais nécessite une authentification multifacteur pour accéder à la partie administration. Traduit autrement : tant que l’utilisateur réalise des actions simples dans l’application, une authentification simple suffit, mais dès que l’utilisateur souhaite réaliser des tâches d’administration, une preuve d’authentification supplémentaire est nécessaire.

Le mécanisme de Step-Up correspond à la demande de la preuve supplémentaire de vérification de l’identité de la personne, cette demande est faite par une application au fournisseur d’identité. Un des buts est de diminuer les frictions pour accéder aux fonctionnalités standards de l’application ; puis pour accéder à certaines fonctionnalités définies par l’application elle-même, demander une vérification supplémentaire de l’identité de la personne.

Cette demande de Step-Up est à l’initiative de l’application, c’est elle qui pilote le fournisseur d’identité en lui demandant un certain niveau de vérification de l’identité de la personne. Niveau de confiance que nous pouvons traduire en niveau d’authentification (ou niveau d’assurance de l’identité) côté fournisseur d’identité.

# Deux mots sur le LOA

Le sigle LOA signifie “Level of Assurance”. Ce terme peut notamment être vu dans les spécifications OpenID Connect avec la notion de Authentication Context (nous y reviendrons plus tard dans l’article).

À noter que le sigle LOA est également présent dans la documentation de Keycloak avec pour signification “Level of Authentication”.

Le LOA est une notion de sécurité qui définit le niveau d’assurance de l’identité d’une personne. Cette notion est portée par le fournisseur d’identité. Charge à celui-ci de faire correspondre un LOA avec une ou plusieurs méthodes d’authentification. Le LOA peut être transmis aux applications clientes dans un claim, au même titre que d’autres informations sur l’utilisateur. Les applications clientes connaissent donc le niveau d’assurance qu’elles peuvent accorder à l’identité d’un utilisateur authentifié par le fournisseur d’identité.

Lorsque ce niveau d’assurance ne correspond pas aux attentes d’une application, celle-ci réalise alors une demande de Step-Up au fournisseur d’identité et celui-ci va mettre en œuvre les méthodes d’authentification nécessaires pour atteindre le LOA demandé par l’application.

Décrit autrement, une authentification classique suit les étapes suivantes :

  1. j’arrive sur une application pour laquelle je n’ai pas encore de session
  2. celle-ci me renvoie vers le fournisseur d’identité pour authentifier mon identité (sans préciser de LOA)
  3. le fournisseur d’identité m’authentifie de manière simple avec un seul facteur d’authentification (généralement via identifiant et mot de passe)
  4. mon LOA au niveau du fournisseur d’identité correspond à une valeur basse (un seul facteur d’authentification)
  5. je peux accéder à l’application

    Et maintenant les étapes correspondant au Step-Up utlisant le LOA :

  6. plus tard, je souhaite accéder à une fonctionnalité sécurisée de l’application, celle-ci détermine que mon niveau d’authentification est trop bas et fait une demande de Step-Up au fournisseur d’identité avec un LOA supérieur
  7. le fournisseur d’identité me reconnait (merci la session et le SSO) et connait mon LOA actuel
  8. mon LOA ne correspond pas au LOA demandé par l’application
  9. le fournisseur d’identité me demande alors une preuve supplémentaire qui se traduit généralement par un second facteur d’authentification
  10. mon LOA au niveau du fournisseur d’identité a maintenant une valeur supérieure
  11. je repars vers l’application avec mon nouveau LOA
  12. je peux accéder à la fonctionnalité sécurisée

À noter qu’à l’étape 9, le fournisseur d’identité ne redemande pas le premier facteur d’authentification (identifiant et mot de passe), ma session indique que cette étape est déjà réalisée et il n’y a pas de nécessité de la refaire. Le fournisseur d’identité va juste compléter ce qui est nécessaire pour atteindre le LOA demandé via un second facteur d’authentification.

Le LOA n’est pas limité à deux niveaux. Un Step-Up / LOA sur deux niveaux correspond au cas le plus souvent rencontré, mais il est possible d’en avoir bien plus. Par exemple :

  • niveau 1 : identifiant et mot de passe
  • niveau 2 : TOTP
  • niveau 3 : webauthn avec clé de sécurité physique
  • niveau 4 : etc.

# Comment OpenID Connect gère le Step-Up / LOA ? 

Le mécanisme de Step-Up et la notion de LOA sont présents dans le protocole OpenID Connect. Ils sont regroupés sous les termes Authentication Context et notamment Authentication Context Class Reference (ACR).

Un ACR est un identifiant qui correspond à un ensemble de méthodes ou procédures d’authentification. Cet identifiant doit être connu à la fois du fournisseur d’identité (pour le faire correspondre à un LOA et donc à un ensemble de facteurs d’authentification) et de l’application cliente (afin de déterminer le niveau de confiance qu’elle peut accorder à l’identité de la personne). Il n’y a pas de règle stricte pour déterminer les valeurs possibles pour ACR, ce sont des identifiants que vous êtes libre de définir.

Dans le cadre de l’utilisation classique de OpenID Connect, lors de la demande d’authentification, l’application renvoie l’utilisateur vers l’URL d’authentification du fournisseur d’identité. Cette URL contient des paramètres classiques tels que “client_id”, “redirect_uri”, “scope”, etc.

Pour réaliser une demande d’authentification avec un ACR précis, il est nécessaire d’ajouter des paramètres supplémentaires. Cela peut se faire de plusieurs manières : via le paramètre “claims” ou via le paramètre “acr_values”.

# Paramètre « Claims »

Ce paramètre permet d’indiquer un (ou plusieurs) identifiant(s) ACR et si celui-ci est “essential” ou non. Le paramètre “claims” contient du json et peut ressembler à ceci :

claims={

    « id_token »: {

        « acr »: {

            « essential »: true,

            « values »: [

                « identifiant_acr »

            ]

        }

    }

}

  • si “essential” est défini à “true”, alors le fournisseur d’identité considère que l’authentification est en échec si le niveau demandé ne peut pas être atteint
  • si “essential” n’est pas précisé, alors le fournisseur d’identité n’est pas contraint d’atteindre le niveau d’authentification demandé pour considérer l’authentification comme réussie

# Paramètre « acr_values »

L’utilisation de ce paramètre est plus simple que “claims”. Il permet également d’indiquer un (ou plusieurs) identifiant(s) ACR, par contre la notion de “essential” disparaît.

Ainsi, “acr_values=identifiant_acr” est l’équivalent de :

claims={

    « id_token »

        « acr »: {

            « values »: [

                « identifiant_acr »

            ]

        }

    }

}

# Retour vers l’application

Si l’authentification réussit, alors le fournisseur d’identité redirige l’utilisateur vers l’application à l’origine de la demande. L’application a alors accès aux informations liées à l’identité de l’utilisateur via des “claims” présents dans l’ID Token. On y retrouve notamment le username de l’utilisateur.

Si l’application en fait la demande, le claim “acr” peut également être présent dans l’ID Token. La valeur du claim “acr” correspond à la valeur ACR atteint lors de la phase d’authentification.

Si, lors de la demande d’authentification, le ACR demandé n’est pas ”essentiel” alors la valeur du claim “acr” peut être différente de la valeur demandée. Charge à l’application de vérifier que le LOA atteint correspond bien au niveau souhaité.

# Concrètement dans Keycloak

Pour utiliser le Step-Up / LOA avec Keycloak, il faut au minimum :

  • créer un flow d’authentification pour gérer le Step-Up / LOA
  • configurer un client (ou le realm) pour faire le lien entre la valeur ACR demandée par le client et le LOA du flow d’authentification

# Flow d’authentification pour Step-Up / LOA

La documentation de Keycloak décrit en détail la création d’un tel flow. Le flow ainsi créé va permettre d’avoir deux niveaux d’authentification :

  • premier niveau avec uniquement le formulaire identifiant et mot de passe
  • et un second niveau avec TOTP

La partie intéressante de ce flow correspond aux étapes “Condition – Level of Authentication”. Ce sont ces étapes qui sont conditionnées par le LOA demandé (et donc de la valeur ACR demandée par l’application). Ainsi, un LOA avec une valeur de 1 déclenche uniquement la condition “1st Condition Flow” alors qu’un LOA avec une valeur de 2 déclenche en plus la condition “2nd Condition Flow”.

La configuration d’une étape “Condition – Level of Authentication” nécessite trois informations :

  • un alias : un texte libre pour identifier l’étape
  • la valeur  LOA associée : un nombre entier (1 pour niveau 1, 2 pour niveau 2, etc.)
  • la durée de validité du LOA (“max-age”) : le LOA atteint dans Keycloak par un utilisateur est conservé pendant un certain temps, passé ce délais l’utilisateur perd automatiquement ce LOA

Ainsi un “max-age” de 0 (comme indiqué dans la capture d’écran), considérera l’utilisateur avec un LOA de 2 uniquement pour cette demande d’authentification et repassera au niveau 1 immédiatement après la fin du flow d’authentification.

On utilise généralement un “max-age” élevé pour le niveau 1 (afin d’éviter à l’utilisateur de renseigner son identifiant et mot de passe trop souvent) et une valeur faible, voire zéro, pour les niveaux supérieurs.

# Mapping ACR / LOA

Cette configuration permet de faire le lien entre la valeur ACR demandée par le client et le LOA équivalent dans Keycloak. Pour rappel, la valeur ACR correspond à un identifiant convenu entre le fournisseur d’identité et l’application cliente, c’est une valeur libre.

Pour schématiser :

  1. l’application fait une demande d’authentification avec “acr_values=mfa
  2. dans Keycloak, la valeur ACR “mfa” est lié au LOA de valeur 2
  3. le flow d’authentification se déroule avec LOA=2 et va donc déclencher la condition “2nd Condition Flow” et demander le code TOTP à l’utilisateur

Ce mapping ACR / LOA peut être réalisé dans la configuration de Keycloak :

  • soit au niveau du realm (dans Realm settings > General > ACR to LoA Mapping)
  • soit directement pour un client (dans Clients > sélectionner le client > Advanced > Advanced Settings > ACR to LoA Mapping), dans ce cas il est également possible de définir une valeur par défaut pour ACR si l’application ne le précise pas

# Et pour les autres protocoles d’authentification ? 

Nous avons beaucoup parlé de OpenID Connect pour lequel nous avons vu comment Keycloak fait le lien entre la valeur ACR (défini par le protocole OIDC) et le LOA (notion propre au fournisseur d’identité). Mais est-il possible de réaliser l’équivalent avec d’autres protocoles d’authentification ?

Pour le protocole CAS, rien n’est prévu dans le protocole lui-même, mais un équivalent est disponible dans le serveur Apereo CAS avec la gestion de niveau d’authentification par application. Le niveau d’authentification est donné pour une application dans son ensemble et il n’est pas prévu qu’une même application puisse faire du Step-Up pour un sous-ensemble de ses fonctionnalités comme décrit en début d’article.

Cette fonctionnalité est dépendante de l’implémentation faite dans le serveur Apereo CAS, il n’y a aucune garantie qu’une autre implémentation de CAS propose le même mécanisme.

Pour le protocole SAML, il existe un équivalent dans le protocole, mais son implémentation dans Keycloak n’est pas encore disponible. Vous pouvez suivre l’évolution de cette demande dans le ticket Step-up authentication for SAML clients.

# Ce qu’il faut retenir 

  • Les mécanismes de Step-Up et LOA permettent de garantir un certain niveau de confiance en l’identité de la personne.
  • Ce niveau de confiance souhaité est à l’initiative de l’application, c’est elle qui pilote le fournisseur d’identité afin d’atteindre ce niveau.
  • Il faut prévoir une coopération entre l’application et le fournisseur d’identité afin de définir les différents niveaux possibles (cela se traduit par le choix des identifiants ACR).
  • Keycloak propose en standard la prise en charge de ces mécanismes …
  • … tant qu’on reste sur le protocole OpenID Connect