Skip to Content

API OAuth 2.0 Avancé

Auris fournit des implémentations des spécifications OAuth 2.0 et OIDC avancées pour les scénarios enterprise. Ces fonctionnalités incluent le Device Authorization Flow pour les appareils sans navigateur, le Token Exchange pour l’impersonation et la délégation, les tokens DPoP (Demonstrating Proof of Possession) liés à l’expéditeur, l’authentification CIBA (Client-Initiated Backchannel Authentication) et l’évaluation du risque avec MFA adaptatif.

Toutes les fonctionnalités OAuth 2.0 avancées doivent être activées pour chaque application dans la Console Auris (Console > Applications > [Nom App] > OAuth Avancé) avant de pouvoir être utilisées.

Device Authorization Flow (RFC 8628)

Le Device Authorization Flow permet aux appareils avec des capacités d’entrée limitées (smart TV, terminaux CLI, appareils IoT) d’obtenir des tokens OAuth 2.0. L’appareil affiche un code utilisateur court et une URL ; l’utilisateur complète l’authentification sur un appareil séparé.

POST/api/oauth/device-authorize

Lance le Device Authorization Flow. Retourne un device_code, un user_code à afficher à l’utilisateur et les métadonnées de polling.

Corps de la requête

{ "client_id": "app_abc123", "scope": "openid profile email" }

Réponse de succès

{ "ok": true, "data": { "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS", "user_code": "WDJB-MJHT", "verification_uri": "https://api.altovar.net/hosted/device", "verification_uri_complete": "https://api.altovar.net/hosted/device?user_code=WDJB-MJHT", "expires_in": 1800, "interval": 5 } }
ChampDescription
device_codeCode opaque long pour l’appareil. Utilisé pour le polling de l’endpoint token. Ne l’affiche jamais à l’utilisateur.
user_codeCode court lisible (format XXXX-XXXX) à afficher sur l’écran de l’appareil.
verification_uriURL où l’utilisateur doit naviguer sur son appareil secondaire.
verification_uri_completeURL pratique avec user_code pré-rempli (pour QR code).
expires_inSecondes avant l’expiration du device_code (1800 = 30 minutes).
intervalSecondes minimum à attendre entre les tentatives de polling. Un polling plus fréquent retourne slow_down.

Codes d’erreur

CodeHTTPDescription
DEVICE_FLOW_DISABLED400Device Flow non activé pour cette application
VALIDATION_ERROR400client_id manquant ou invalide

Polling pour le Token

Une fois le user_code affiché à l’utilisateur, l’appareil doit effectuer un polling sur l’endpoint token jusqu’à ce que l’utilisateur autorise la demande, que le code expire ou que l’utilisateur refuse l’accès.

{ "grant_type": "urn:ietf:params:oauth:grant-type:device_code", "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS", "client_id": "app_abc123" }
Réponse pollingDescription
AUTHORIZATION_PENDINGL’utilisateur n’a pas encore complété l’autorisation. Réessaie après interval secondes.
SLOW_DOWNTu fais le polling trop fréquemment. Augmente l’intervalle de polling de 5 secondes.
EXPIRED_TOKENLe device_code a expiré. Lance un nouveau flux.
ACCESS_DENIEDL’utilisateur a refusé la demande d’autorisation.
Réponse tokenL’utilisateur a autorisé. Réponse token standard avec access_token, refresh_token, id_token.

La page de vérification hébergée par Auris est disponible sur /hosted/device. Elle affiche un formulaire pour saisir le code utilisateur, effectue l’authentification si nécessaire, et confirme l’autorisation de l’appareil.

Token Exchange (RFC 8693)

Le Token Exchange permet à un service d’obtenir des tokens en agissant comme un autre utilisateur (impersonation) ou pour le compte d’un autre utilisateur (délégation). Les deux nécessitent des permissions explicites et génèrent des entrées complètes dans le journal d’audit.

POST/api/auth/tokenRequires: impersonate:users ou delegate:tokens

Échange un token existant contre un nouveau token représentant une identité ou un contexte différent. Supporte à la fois le pattern d’impersonation (agir comme un utilisateur) et le pattern de délégation (agir pour le compte d’un utilisateur).

Impersonation

Le service demandeur agit entièrement comme l’utilisateur cible. Le token résultant a l’ID de l’utilisateur cible comme sub. Tous les événements d’audit montrent l’impersonation.

{ "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", "subject_token": "eyJhbGciOiJSUzI1NiJ9...", "subject_token_type": "urn:ietf:params:oauth:token-type:access_token", "requested_token_type": "urn:ietf:params:oauth:token-type:access_token", "exchange_type": "impersonation", "target_user_id": "usr_target123" }

Réponse — token standard avec "sub": "usr_target123"

Délégation

Le service demandeur agit pour le compte de l’utilisateur original. Le sujet original est préservé dans le token. Le claim act identifie le principal qui agit.

{ "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", "subject_token": "eyJhbGciOiJSUzI1NiJ9...", "subject_token_type": "urn:ietf:params:oauth:token-type:access_token", "requested_token_type": "urn:ietf:params:oauth:token-type:access_token", "exchange_type": "delegation" }

Payload JWT résultant

{ "sub": "usr_original123", "act": { "sub": "usr_acting_service456" }, "scope": "read:data" }

Champs de la requête

ChampObligatoireDescription
grant_typeOuiDoit être urn:ietf:params:oauth:grant-type:token-exchange
subject_tokenOuiLe token d’accès de l’utilisateur original pour le compte duquel on agit
subject_token_typeOuiDoit être urn:ietf:params:oauth:token-type:access_token
requested_token_typeOuiDoit être urn:ietf:params:oauth:token-type:access_token
exchange_typeOuiimpersonation ou delegation
target_user_idPour impersonationRequis pour l’impersonation ; l’utilisateur à impersonner
scopeNonSous-ensemble des scopes du token original à inclure dans le nouveau token

Codes d’erreur

CodeHTTPDescription
TOKEN_EXCHANGE_DISABLED400Token Exchange non activé pour cette application
INVALID_SUBJECT_TOKEN401Le token sujet n’est pas valide ou a expiré
TARGET_USER_NOT_FOUND404Le target_user_id ne correspond à aucun utilisateur existant
PERMISSION_DENIED403Permission manquante (impersonate:users ou delegate:tokens)
SCOPE_EXCEEDS_ORIGINAL400Les scopes demandés dépassent ceux du token sujet original

DPoP — Demonstrating Proof of Possession (RFC 9449)

Les tokens DPoP sont cryptographiquement liés au client qui les a obtenus. Contrairement aux tokens Bearer standard, les tokens DPoP ne peuvent pas être utilisés par un attaquant qui les intercepte car les appels API nécessitent une preuve JWT fraîche signée avec la clé privée du client.

Comment Fonctionne DPoP

  1. Génération des clés : Le client génère une paire de clés à courbe elliptique (EC P-256 ou RSA). La clé privée ne quitte jamais le client.
  2. Création de la preuve : Pour chaque requête, le client crée un JWT de preuve DPoP signé avec la clé privée, incluant la méthode HTTP, l’URL et un jti unique.
  3. Binding du token : Le serveur valide la preuve, extrait le thumbprint JWK et lie le token émis à cette clé publique.
  4. Appels API : Les appels API suivants nécessitent à la fois le token DPoP et une nouvelle preuve DPoP fraîche pour cette requête spécifique.

Structure de la Preuve DPoP

DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik...

Le JWT de preuve DPoP a la structure suivante :

Header

{ "typ": "dpop+jwt", "alg": "ES256", "jwk": { "kty": "EC", "crv": "P-256", "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU", "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0" } }

Payload

{ "htm": "POST", "htu": "https://api.altovar.net/api/auth/token", "iat": 1707300000, "jti": "unique-id-per-request-abc123", "nonce": "server-provided-nonce" }
ChampDescription
htmMéthode HTTP de la requête (GET, POST, etc.)
htuURL complète de la requête sans query string
iatIssued At — le décalage d’horloge autorisé est de 30 secondes
jtiIdentifiant unique pour cette preuve spécifique (prévient le replay)
nonceNonce fourni par le serveur (obligatoire quand le serveur l’inclut dans la réponse)

Token DPoP dans la Réponse

Lors de l’obtention d’un token avec DPoP, la réponse inclut "token_type": "DPoP" au lieu de "Bearer". Le JWT du token d’accès contient un claim cnf.jkt avec le thumbprint JWK :

{ "sub": "usr_abc123", "cnf": { "jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" } }

Pour utiliser un token DPoP, inclus l’en-tête Authorization: DPoP <token> ainsi qu’un en-tête DPoP: <fresh-proof>.

Gestion du Nonce

Le serveur peut nécessiter un nonce pour prévenir les replays. Inclus le nonce dans les preuves DPoP suivantes :

DPoP-Nonce: eyJ...server-issued-nonce...

Ce nonce doit être inclus dans le claim nonce de ton prochain JWT de preuve DPoP. Si tu envoies une preuve sans nonce quand il est requis, tu recevras une erreur use_dpop_nonce avec un nonce frais dans l’en-tête de la réponse.

Codes d’erreur

CodeHTTPDescription
INVALID_DPOP_PROOF401La preuve DPoP n’est pas valide (signature invalide, expirée, jti réutilisé)
DPOP_NONCE_REQUIRED401Un nonce est requis — voir l’en-tête DPoP-Nonce dans la réponse
DPOP_JKT_MISMATCH401La clé publique dans la preuve ne correspond pas au thumbprint dans le token
DPOP_DISABLED400DPoP non activé pour cette application

CIBA — Authentification Backchannel (Client-Initiated Backchannel Authentication)

CIBA permet à un service de lancer une authentification en arrière-plan sur un appareil ou canal séparé (comme une notification push mobile) sans rediriger le navigateur. Utile pour les centres d’appel, l’authentification à distance et les applications sur des appareils séparés.

POST/api/oauth/backchannel/authorizeRequires: manage:ciba_config

Lance un flux d’authentification backchannel pour l’utilisateur identifié. Auris envoie une notification d’authentification à l’utilisateur (push, notification in-app, etc.). Le service effectue un polling ou attend un callback pour le token.

Corps de la requête

{ "client_id": "app_abc123", "client_secret": "app_secret_xyz", "scope": "openid profile", "login_hint": "[email protected]", "binding_message": "Autoriser paiement 50€ à Jane", "requested_expiry": 300 }
ChampObligatoireDescription
client_idOuiL’identifiant de l’application
client_secretOuiLe secret de l’application
scopeOuiScopes OAuth à demander
login_hintOuiEmail ou ID de l’utilisateur à authentifier
binding_messageNonCourt message lisible affiché à l’utilisateur pour associer la demande à une action. Maximum 256 caractères.
requested_expiryNonSecondes de validité de la demande. Défaut 300, maximum 600.

Réponse de succès

{ "ok": true, "data": { "auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac9", "expires_in": 300, "interval": 5 } }

Modes de Notification

La façon dont ton service reçoit le résultat de l’authentification dépend du mode CIBA configuré pour l’application :

ModeComportement
pollTon service effectue un polling sur l’endpoint token avec auth_req_id
pingAuris envoie un callback HTTP à ton application (notification_endpoint) quand l’utilisateur répond ; puis ton service appelle l’endpoint token
pushAuris envoie le token directement à ton application (notification_endpoint) après la réponse de l’utilisateur

Polling CIBA

Pour le mode poll, effectue un polling sur l’endpoint token :

{ "grant_type": "urn:openid:params:grant-type:ciba", "auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac9", "client_id": "app_abc123", "client_secret": "app_secret_xyz" }

Les réponses de polling fonctionnent de la même façon que le Device Flow : AUTHORIZATION_PENDING, SLOW_DOWN, EXPIRED_TOKEN, ACCESS_DENIED, ou un token de succès.

Codes d’erreur

CodeHTTPDescription
CIBA_DISABLED400CIBA non activé pour cette application
USER_NOT_FOUND404L’utilisateur spécifié dans login_hint n’existe pas
NOTIFICATION_FAILED502Auris n’a pas pu envoyer la notification à l’appareil de l’utilisateur
BINDING_MESSAGE_TOO_LONG400Le binding_message dépasse 256 caractères

Évaluation du Risque et MFA Adaptatif

Auris évalue le risque de chaque événement d’authentification en temps réel. Sur la base du score de risque, il peut autoriser la connexion, demander une étape MFA supplémentaire, ou bloquer complètement la tentative d’authentification.

Facteurs de Risque

Chaque facteur contribue à hauteur de 20% au score de risque global :

FacteurDescription
Réputation IPVérifie si l’IP source est une IP malveillante connue, un VPN, un proxy ou un réseau datacenter
Confiance AppareilDétermine si l’empreinte de l’appareil a déjà été vue pour cet utilisateur
Anomalie GéographiqueDétecte les voyages impossibles et les localisations géographiques inhabituelles
ComportementAnalyse les patterns de connexion comme l’heure inhabituelle et les tentatives d’accès échouées répétées
Sensibilité de l’ActionLa sensibilité de l’action demandée (opération normale vs. opération critique de sécurité)

Niveaux de Risque

NiveauScoreAction par défaut
LOW0–30Autoriser la connexion
MEDIUM31–60Demander MFA
HIGH61–80Demander MFA fort (clé matérielle ou biométrie)
CRITICAL81–100Bloquer la connexion

Claims JWT ACR et AMR

Les tokens Auris incluent des claims OIDC standard qui décrivent comment l’utilisateur s’est authentifié :

Claim acr (Authentication Context Class Reference)

ValeurDescription
urn:auris:acr:pwdAuthentification par mot de passe uniquement
urn:auris:acr:mfaAuthentification multi-facteur complétée
urn:auris:acr:strongMFA fort avec clé matérielle ou biométrie

Claim amr (Authentication Methods References)

Tableau des méthodes utilisées lors de l’authentification : pwd, otp, sms, webauthn, social, magic_link, sso

{ "sub": "usr_abc123", "acr": "urn:auris:acr:mfa", "amr": ["pwd", "otp"] }

API d’Évaluation du Risque

GET/api/auth/risk/assessmentsRequires: view:risk_assessments

Liste les évaluations de risque d’authentification avec filtres. Chaque entrée inclut le score de risque, les facteurs contributeurs et l’action prise par le moteur de risque.

Paramètres de requête

ParamètreTypeDescription
pagenumberNuméro de page (défaut : 1)
limitnumberRésultats par page (défaut : 20, max : 100)
userIdstringFiltrer par ID utilisateur spécifique
levelstringFiltrer par niveau de risque : LOW, MEDIUM, HIGH, CRITICAL
dateFromstringDate de début ISO 8601
dateTostringDate de fin ISO 8601

Exemple de réponse

{ "ok": true, "data": [ { "id": "risk_abc123", "userId": "usr_xyz789", "score": 72, "level": "HIGH", "factors": { "ipReputation": 20, "deviceTrust": 0, "geoAnomaly": 20, "behavior": 12, "actionSensitivity": 20 }, "actionTaken": "step_up_mfa", "ipAddress": "203.0.113.42", "country": "FR", "city": "Paris", "createdAt": "2025-02-18T14:30:00Z" } ], "pagination": { "page": 1, "limit": 20, "total": 142, "pages": 8 } }

Règles de Risque Personnalisées

Tu peux étendre le moteur d’évaluation du risque avec des règles custom qui remplacent ou augmentent le comportement par défaut.

GET/api/auth/risk/rulesRequires: manage:risk_rules

Liste toutes les règles de risque custom configurées pour le tenant.

POST/api/auth/risk/rulesRequires: manage:risk_rules

Crée une nouvelle règle de risque custom. Les règles sont évaluées à chaque événement d’authentification.

Corps de la requête

{ "name": "Bloquer les accès depuis des proxies connus", "condition": { "field": "ipReputation.isProxy", "operator": "equals", "value": true }, "action": "block", "scoreModifier": 50, "isActive": true }
ChampObligatoireDescription
nameOuiNom descriptif pour la règle
conditionOuiLa condition à évaluer (voir tableau des champs ci-dessous)
actionOuiAction : allow, step_up_mfa, block, log
scoreModifierNonAjoute cette valeur (0–100) au score de risque quand la condition est vraie
isActiveOuiSi la règle est active

Champs de condition disponibles

ChampTypeDescription
ipReputation.isVpnbooleanL’IP est un VPN
ipReputation.isProxybooleanL’IP est un proxy
ipReputation.isDatacenterbooleanL’IP est dans une plage datacenter
deviceTrust.isNewDevicebooleanL’appareil n’a jamais été vu auparavant pour cet utilisateur
geoAnomaly.isNewCountrybooleanConnexion depuis un pays jamais vu auparavant pour cet utilisateur
geoAnomaly.distancenumberDistance en km depuis la précédente localisation de connexion
behavior.unusualTimebooleanConnexion à une heure inhabituelle pour cet utilisateur
behavior.failedAttemptsnumberNombre de tentatives récentes échouées

Opérateurs disponibles

equals, not_equals, greater_than, less_than, contains, in

PUT/api/auth/risk/rules/[id]Requires: manage:risk_rules

Met à jour une règle de risque existante. Accepte les mêmes champs que la création. Tu peux mettre à jour partiellement (seuls les champs spécifiés sont modifiés).

DELETE/api/auth/risk/rules/[id]Requires: manage:risk_rules

Supprime définitivement une règle de risque custom. La suppression est irréversible.

Référence des Permissions

PermissionDescription
manage:device_codesActive et utilise le Device Authorization Flow
impersonate:usersExécute Token Exchange avec exchange_type: "impersonation"
delegate:tokensExécute Token Exchange avec exchange_type: "delegation"
manage:dpop_configConfigure les paramètres DPoP pour les applications
manage:ciba_configConfigure et lance les demandes d’authentification CIBA
view:risk_assessmentsLit les logs et données d’évaluation du risque
manage:risk_rulesCrée, met à jour et supprime les règles de risque custom
manage:advanced_oauthConfiguration OAuth 2.0 avancé complète

Corrélés