Graphes d'authentification


Les graphes d’authentification sont l’architecture d’authentification moderne de TOSIAM, implémentée dans le module tosiam-graph. Ils remplacent les chaînes de modules statiques par un modèle flexible de nœuds connectés, permettant de concevoir visuellement des parcours d’authentification complexes.

Concept

Un graphe est un graphe orienté où chaque nœud (GraphNode) reçoit un contexte mutable (GraphContext) et retourne un résultat qui détermine la transition suivante :

RésultatSignification
REQUEST_INPUTAfficher des callbacks à l’utilisateur (formulaire)
GO_TOTransitionner vers un autre nœud selon un outcome
SUCCESSAuthentification réussie (nœud terminal)
FAILUREAuthentification échouée (nœud terminal)
SUB_GRAPH_EXITSortir d’un sous-graphe par une sortie nommée

Le moteur (GraphEngine) itère jusqu’à 100 transitions consécutives avant de forcer un échec.

Contexte partagé

Tous les nœuds d’un graphe partagent un GraphContext contenant :

  • sharedState — état mutable (nom d’utilisateur, score de risque, flags…)
  • submittedCallbacks — données saisies par l’utilisateur
  • requestHeaders — en-têtes HTTP de la requête (RFC 7230)

Créer et gérer des graphes

Via le Graph Designer (interface admin)

L’éditeur visuel est accessible dans la console d’administration TOSIAM à /authgraphs. Il permet :

  • Créer, dupliquer, importer et exporter des graphes
  • Glisser-déposer des nœuds depuis une palette par catégorie
  • Connecter les outcomes entre nœuds par des fils colorés
  • Valider en temps réel (nœuds orphelins, outcomes non connectés)
  • Tester le flux directement depuis l’éditeur (TestLoginComponent)
  • Naviguer dans les sous-graphes (breadcrumbs)
  • Mise en page automatique BFS Tidy

Via l’API REST

GET    /json/{realm}/authgraph              → lister les graphes
GET    /json/{realm}/authgraph/{name}       → lire un graphe
POST   /json/{realm}/authgraph?_action=create → créer
PUT    /json/{realm}/authgraph/{name}       → mettre à jour
DELETE /json/{realm}/authgraph/{name}       → supprimer

Via ssoadm

ssoadm create-auth-graph --realm / --name monGraphe --jsonfile graphe.json
ssoadm list-auth-graphs  --realm /
ssoadm show-auth-graph   --realm / --name monGraphe
ssoadm update-auth-graph --realm / --name monGraphe --jsonfile graphe.json
ssoadm delete-auth-graph --realm / --name monGraphe

Exposer un graphe comme point d’entrée

Pour rendre un graphe accessible à l’authentification, on crée une instance du module graph-module :

POST /realms/{realm}/realm-config/authentication/modules/graph-module
{
  "graphId": "monGraphe",
  "iplanet-am-auth-auth-level": "0"
}

L’URL d’authentification devient alors :

/tosiam/realms/{realm}/authenticate?service=monGraphe

Catalogue des nœuds natifs

TOSIAM fournit 60 nœuds natifs (module tosiam-graph, sauf mention contraire), organisés en familles. Chaque famille a sa propre page, avec le détail des propriétés de configuration et des outcomes réels de chaque nœud (souvent plus riches qu’un simple true/false : enrolled/notEnrolled, allowed/blocked/suspicious, low/medium/high…) :

FamilleNœuds
CollecteursUsername, Password, Phone
DécisionsDataStore, AccountLockStatus, Lockout, AuthLevel, RetryLimit, BearerToken, StepUpAuth, Script
MFA — TOTPTotpVerifier, TotpSecretGenerator, TotpEnrollCommit, TotpQrCodeDisplay, TotpRecoveryCodesDisplay, RecoveryCodeVerify, MfaEnrollmentCheck, MfaChoice, MfaPolicyDecision
OTP SMS / EmailSmsOtpSend, SmsOtpVerify, EmailOtpSend, EmailOtpVerify
Magic LinkMagicLinkSend, MagicLinkVerify
Passkeys / WebAuthnPasskeyEnrollmentCheck, PasskeyRegistration, PasskeyAuthentication
CAPTCHA / Anti-botRecaptchaV2, RecaptchaV2Invisible, RecaptchaV3, Turnstile, HCaptcha
Risque adaptatifDeviceFingerprint, GeoLocationDecision, ImpossibleTravel, RiskScore
Certificat / PKICertificateCollector, CertificateValidation
SAML 2.0SamlRedirect, SamlCallback
Social Login / OIDCSelectSocialProvider, OidcRedirect, OidcCallback, OAuth2Callback, FetchUserInfo, NormalizeProfile, EmailVerifiedDecision, AutoProvisionUser, SocialAccountLinking
SSO PersistantPersistentSso, SetPersistentSso
Lifecycle utilisateurConsent, TermsAndConditions, PasswordChange, PasswordExpiration, PasswordHistory, ProfileCompleteness
Session & UtilitairesSetSessionProperties, Page, SubGraph, SubGraphExit, Success, Failure

Un exemple concret de graphe (boucle de nouvelle tentative avec RetryLimitNode) est disponible sur la page Nœuds — Décisions.

Sous-graphes

Les sous-graphes permettent de factoriser des séquences réutilisables (ex: un bloc “vérification MFA” partagé entre plusieurs graphes principaux).

ssoadm create-sub-graph --realm / --name verif-mfa --jsonfile verif-mfa.json
ssoadm list-sub-graphs  --realm /

Un SubGraphNode inclut un sous-graphe en y accédant par son nom. Ses SubGraphExitNode définissent les sorties nommées disponibles pour le graphe parent.

Format JSON d’un graphe

{
  "startNodeId": "node-1",
  "steps": {
    "node-1": {
      "type": "UsernameCollectorNode",
      "config": {},
      "outcomes": { "outcome": "node-2" }
    },
    "node-2": {
      "type": "PasswordCollectorNode",
      "config": {},
      "outcomes": { "outcome": "node-3" }
    },
    "node-3": {
      "type": "DataStoreNode",
      "config": {},
      "outcomes": {
        "true": "success",
        "false": "failure"
      }
    },
    "success": { "type": "SuccessNode", "config": {}, "outcomes": {} },
    "failure": { "type": "FailureNode", "config": {}, "outcomes": {} }
  }
}

Validation

Le Graph Designer vérifie automatiquement :

CodeNiveauCondition
no-startErreurAucun nœud de départ défini
broken-edgeErreurOutcome vers un nœud inexistant
dangling-subgraphErreurRéférence à un sous-graphe inexistant
dead-endAvertissementOutcome non connecté
unreachableAvertissementNœud non atteignable depuis le départ

Extension par SPI

Pour ajouter un nœud personnalisé, implémenter GraphNode et annoter avec @NodeMetadata :

@NodeMetadata(type = "MyCustomNode", configClass = MyConfig.class, outcomeProvider = MyOutcomes.class)
public class MyCustomNode implements GraphNode {
    @Override
    public NodeResult process(GraphContext context) {
        // logique métier
        return NodeResult.goTo("true");
    }
}

Les services injectables incluent : EmailSenderService, SmsSenderService, PasskeyService, GeoLocationService, DeviceFingerprintStore, UserProvisioningService, RecaptchaVerificationService.

Modifier cette page sur GitHub