Qu’est-ce que la step-up authentication ?
La step-up authentication est un mécanisme de sécurité qui exige d’un utilisateur qu’il se ré-authentifie avec un niveau d’assurance plus élevé lorsqu’il accède à des ressources sensibles ou effectue des actions critiques. Elle garantit que l’utilisateur à l’origine de la demande possède une identité vérifiée, en adéquation avec la sensibilité de l’opération ou des données.
Si vous souhaitez en savoir plus sur la step-up authentication avec OpenID Connect, consultez notre article Step-Up Authentication avec OpenID Connect. La mise en œuvre avec Auth0 est similaire, mais la configuration est spécifique à la plateforme Auth0.
Comment fonctionne la step-up authentication ?
Lorsqu’un utilisateur s’authentifie auprès d’Auth0, la plateforme émet un ID token contenant des claims sur l’événement d’authentification et sur l’utilisateur. En incluant des claims spécifiques dans l’ID token, vous pouvez imposer une step-up authentication en fonction du contexte de l’utilisateur ou de l’opération demandée.
Ces claims permettent de déterminer le niveau d’assurance apporté par l’authentification et de savoir si une step-up authentication est nécessaire. Par exemple, vous pouvez utiliser le claim acr (Authentication Context Class Reference) pour représenter la classe de contexte d’authentification utilisée pendant le processus.
Step-up authentication avec le claim acr
Le claim acr de l’ID token représente la classe de contexte d’authentification utilisée pendant le processus. Il peut par exemple indiquer le niveau d’assurance apporté par l’authentification de l’utilisateur dans la session en cours. Ainsi, acr=loa1 correspond à un niveau d’assurance basique, comme une authentification par mot de passe.
Lorsqu’un utilisateur s’authentifie, Auth0 inclut le claim acr dans l’ID token selon le niveau d’assurance obtenu. Votre application peut alors évaluer ce claim pour déterminer si une step-up authentication est nécessaire pour l’opération demandée.
Auth0 définit des valeurs courantes pour le claim acr, mais vous pouvez aussi définir des valeurs personnalisées selon les besoins de votre application. La valeur la plus courante est http://schemas.openid.net/pape/policies/2007/06/multi-factor, qui indique qu’une authentification multi-facteur (MFA) a été utilisée pendant l’authentification.
Auth0 supporte également le claim amr (Authentication Methods References), qui fournit des informations sur les méthodes d’authentification employées. Ce claim permet de déterminer précisément quelles méthodes ont été appliquées.
Exemple :
{ "iss": "https://{yourDomain}/", "sub": "auth0|1a2b3c4d5e6f7g8h9i", "aud": "{yourClientId}", "iat": 1522838054, "exp": 1522874054, "acr": "http://schemas.openid.net/pape/policies/2007/06/multi-factor", "amr": ["mfa"]}Mettre en place la step-up authentication avec Auth0
Pour mettre en place la step-up authentication avec Auth0, vous devez développer une Action Auth0 personnalisée de type post-login qui évalue les acr_values jointes à la requête OpenID Connect. Le paramètre acr_values permet de demander des classes de contexte d’authentification spécifiques pendant l’authentification.
Vous pouvez ensuite challenger l’utilisateur avec des facteurs d’authentification supplémentaires. Par exemple, vous pouvez lui demander un mot de passe à usage unique (OTP) ou une vérification biométrique, selon l’opération demandée ou les facteurs enrôlés.
Exemple avec acr_values
Voici un exemple d’Action Auth0 personnalisée qui impose une step-up authentication en fonction des acr_values :
/** * Handler that will be called during the execution of a PostLogin flow. * * @param {Event} event - Details about the user and the context in which they are logging in. * @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login. */exports.onExecutePostLogin = async (event, api) => { // Step-up is trigger depending on a specific acr value if ( !event.transaction?.acr_values?.includes( 'http://schemas.openid.net/pape/policies/2007/06/multi-factor', ) ) { return }
// Check if offline access is requested. If so, deny the request because we don't allow refresh tokens in this context. if ( event.transaction.requested_scopes?.some((scope) => ['offline_access', 'offline'].includes(scope), ) ) { return api.access.deny('offline_access_not_allowed') }
api.multifactor.enable('any', { allowRememberBrowser: false }) return api.authentication.challengeWithAny([ { type: 'otp' }, { type: 'phone' }, { type: 'webauthn-platform' }, { type: 'webauthn-roaming' }, ])}
/** * Handler that will be invoked when this action is resuming after an external redirect. If your * onExecutePostLogin function does not perform a redirect, this function can be safely ignored. * * @param {Event} event - Details about the user and the context in which they are logging in. * @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login. */// exports.onContinuePostLogin = async (event, api) => {// };Exemple avec les scopes
Voici le même exemple, mais en utilisant des scopes sensibles pour déclencher la step-up authentication :
const sensitiveScopes = ['transfer:money', 'view:account']
/** * Handler that will be called during the execution of a PostLogin flow. * * @param {Event} event - Details about the user and the context in which they are logging in. * @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login. */exports.onExecutePostLogin = async (event, api) => { // Step-up is trigger depending on if the OpenID Connect request includes sensitive scopes if ( !event.transaction?.requested_scopes?.some((scope) => sensitiveScopes.includes(scope), ) ) { return }
// Check if offline access is requested. If so, deny the request because we don't allow refresh tokens in this context. if ( event.transaction.requested_scopes?.some((scope) => ['offline_access', 'offline'].includes(scope), ) ) { return api.access.deny('offline_access_not_allowed') }
api.multifactor.enable('any', { allowRememberBrowser: false }) return api.authentication.challengeWithAny([ { type: 'otp' }, { type: 'phone' }, { type: 'webauthn-platform' }, { type: 'webauthn-roaming' }, ])}
/** * Handler that will be invoked when this action is resuming after an external redirect. If your * onExecutePostLogin function does not perform a redirect, this function can be safely ignored. * * @param {Event} event - Details about the user and the context in which they are logging in. * @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login. */// exports.onContinuePostLogin = async (event, api) => {// };