Authentification unique avec SAML 2.0 Module
Comment ça marche
Vaks PM agit comme fournisseur de service SAML. Ses contraintes sont volontairement étroites, et les connaître d'emblée épargne l'essentiel du débogage :
- L'assertion doit être signée (la réponse externe ne l'exige pas), avec des algorithmes de signature et de condensat SHA-256.
- Les assertions chiffrées ne sont pas prises en charge. Il n'y a pas de clé privée côté fournisseur de service : un fournisseur configuré pour chiffrer échouera donc à la validation. Laissez le chiffrement d'assertion désactivé.
- L'assertion est consommée en HTTP POST, et l'audience doit correspondre exactement à l'entity ID du fournisseur de service.
- La tolérance de dérive d'horloge est de 30 secondes. Les fenêtres de validité sont appliquées avec cette marge de part et d'autre : votre fournisseur d'identité comme les hôtes Vaks PM doivent donc toujours faire tourner NTP — au-delà d'une demi-minute de dérive, on retrouve des échecs de validation intermittents et génériques, qui ressemblent à un problème de certificat sans en être un. Un opérateur peut élargir la tolérance avec la variable d'environnement
SSO_SAML_CLOCK_SKEW_MS, plafonnée à cinq minutes ; l'augmenter contourne une horloge fausse au lieu de la corriger. - Les requêtes ne sont pas signées par Vaks PM, puisqu'il ne détient aucune clé privée. Les fournisseurs l'acceptent ; n'exigez pas de requêtes d'authentification signées.
Les attributs à envoyer
C'est la partie qui décide si votre intégration fonctionne, et c'est là que les fournisseurs non-Microsoft demandent de l'attention. Vaks PM lit par défaut les URI de revendication Microsoft, et les noms de revendications ne peuvent pas être changés dans l'interface d'administration. Quel que soit votre fournisseur, configurez-le pour émettre exactement ces noms d'attributs :
| Objet | Nom d'attribut à émettre | Repli si absent |
|---|---|---|
| Clé de compte (obligatoire) | http://schemas.microsoft.com/identity/claims/objectidentifier | Le NameID |
| Email (obligatoire) | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress | email, puis le NameID |
| Nom affiché | http://schemas.microsoft.com/identity/claims/displayname | displayName, puis http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname, puis l'email |
| Groupes (pour le mappage des rôles) | http://schemas.microsoft.com/ws/2008/06/identity/claims/groups | Aucun. Absent signifie aucun mappage de rôle du tout |
Prérequis
| Côté | Ce qu'il vous faut |
|---|---|
| Fournisseur d'identité | Le droit de créer une application ou une relying-party trust et de définir ses attribute statements. |
| Vaks PM | Le droit org:manage — un administrateur d'organisation. |
| Licence | Une licence couvrant l'authentification unique. La configuration fonctionne sans elle ; la connexion fédérée non. |
| Infrastructure | Redis joignable (la poignée de main y est conservée 10 minutes) et des horloges exactes sur chaque hôte. |
Étape 1 — Commencer dans Vaks PM pour obtenir les valeurs du fournisseur de service
Ouvrez Admin → Intégrations → Single sign-on, ajoutez un fournisseur, et renseignez :
- Protocole — SAML. Réglable uniquement à la création.
- Slug — lettres minuscules, chiffres et tirets, de 2 à 40 caractères. Figé une fois enregistré, puisqu'il est incorporé aux URL ci-dessous.
- Nom affiché — le libellé sur le bouton de connexion.
Le formulaire génère alors les trois valeurs dont votre fournisseur a besoin :
| Champ dans Vaks PM | Valeur | Nom courant chez la plupart des fournisseurs |
|---|---|---|
| URL ACS / de réponse (générée) | https://<host>/api/v1/auth/saml/<slug>/callback | Assertion Consumer Service URL, Reply URL, ACS URL |
| SP entityID (Identifier) | https://<host>/api/v1/auth/saml/<slug> | Identifier, Entity ID, Audience URI |
| Métadonnées SP (fichier XML) | https://<host>/api/v1/auth/saml/<slug>/metadata | Métadonnées de fournisseur de service, téléversables chez la plupart des fournisseurs |
Notez que l'entity ID est l'URL ACS sans /callback — ce sont délibérément deux valeurs différentes, et les fournisseurs rejettent l'assertion si l'audience ne correspond pas exactement. Enregistrez le fournisseur dès maintenant, pour pouvoir exporter le fichier de métadonnées ; il reste désactivé jusqu'à ce que vous l'activiez à l'étape 5.
Étape 2 — Dans votre fournisseur d'identité
Microsoft Entra ID
- Rendez-vous dans Microsoft Entra admin center → Identity → Applications → Enterprise applications → New application → Create your own application, choisissez l'option hors galerie, puis ouvrez Single sign-on → SAML.
- Dans Basic SAML Configuration, téléversez le fichier de métadonnées de l'étape 1, ou renseignez Identifier (Entity ID) et Reply URL avec les deux valeurs générées.
- Entra émet déjà l'identifiant d'objet, l'email et le nom affiché sous les URI de revendication attendus : l'attribute statement par défaut fonctionne donc tel quel. Pour le mappage des rôles, ajoutez une group claim sous Attributes & Claims.
- Sous SAML Certificates, téléchargez Certificate (Base64) et copiez la Login URL.
- Affectez les utilisateurs ou groupes qui doivent avoir accès sous Users and groups.
Google Workspace
- Dans la Google Admin console, allez dans Apps → Web and mobile apps → Add app → Add custom SAML app.
- Sur l'écran des détails du fournisseur d'identité Google, téléchargez le certificat et copiez l'SSO URL.
- Pour les détails du fournisseur de service, renseignez ACS URL et Entity ID avec les deux valeurs de l'étape 1. Laissez Signed response décoché — l'assertion est signée par défaut, ce qui est bien ce qui est exigé.
- Sous Attribute mapping, mappez :
- Basic information → Primary email → attribut d'application
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress - Basic information → le nom complet de l'utilisateur →
http://schemas.microsoft.com/identity/claims/displayname. N'y mappez pas le prénom seul — il deviendrait le nom affiché de chaque utilisateur. - Un identifiant stable — l'unique ID de Google — →
http://schemas.microsoft.com/identity/claims/objectidentifier
- Basic information → Primary email → attribut d'application
- Pour le mappage des rôles, ajoutez un mappage group membership et nommez l'attribut d'application
http://schemas.microsoft.com/ws/2008/06/identity/claims/groups. - Activez l'application pour les unités organisationnelles concernées.
Active Directory Federation Services (AD FS)
- Dans la console de gestion AD FS, allez dans Relying Party Trusts → Add Relying Party Trust, choisissez Claims aware, et importez les métadonnées de l'étape 1 par URL si votre hôte AD FS peut les joindre — sinon, saisissez l'entity ID et l'URL ACS à la main.
- Réglez l'algorithme de hachage sécurisé sur SHA-256 dans les propriétés Advanced de la trust.
- Ajoutez une règle de revendication Send LDAP Attributes as Claims contre Active Directory :
- E-Mail-Addresses →
E-Mail Address - Display-Name → une revendication personnalisée nommée
http://schemas.microsoft.com/identity/claims/displayname - objectGUID → une revendication personnalisée nommée
http://schemas.microsoft.com/identity/claims/objectidentifier
- E-Mail-Addresses →
- Ajoutez une deuxième règle pour l'appartenance aux groupes, émettant vers
http://schemas.microsoft.com/ws/2008/06/identity/claims/groups. - Ajoutez une règle transformant l'adresse email en Name ID au format Email.
- Exportez votre certificat de signature de jeton depuis Service → Certificates, et notez l'URL de connexion, généralement
https://<adfs-host>/adfs/ls/.
Okta
- Dans la console d'administration Okta, allez dans Applications → Create App Integration → SAML 2.0.
- Renseignez Single sign-on URL avec l'URL ACS et Audience URI (SP Entity ID) avec l'entity ID, tous deux issus de l'étape 1. Laissez le format de NameID sur EmailAddress.
- Sous Attribute Statements, ajoutez :
- Nom
http://schemas.microsoft.com/identity/claims/objectidentifier, valeuruser.id - Nom
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress, valeuruser.email - Nom
http://schemas.microsoft.com/identity/claims/displayname, valeuruser.displayName
- Nom
- Sous Group Attribute Statements, ajoutez le nom
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsavec un filtre correspondant aux groupes que vous voulez envoyer. - Depuis l'onglet Sign On, récupérez l'URL de connexion du fournisseur d'identité et téléchargez le certificat de signature.
Keycloak
- Dans votre realm, allez dans Clients → Create client, type SAML, et renseignez le client ID avec l'entity ID de l'étape 1 — dans Keycloak, le client ID est l'audience attendue.
- Renseignez Valid redirect URIs et le master SAML processing URL avec l'URL ACS.
- Dans les paramètres du client, activez Sign assertions. Laissez Sign documents à votre convenance, et laissez le chiffrement d'assertion désactivé. Réglez l'algorithme de signature sur RSA-SHA256, et le format de NameID sur email.
- Sous Client scopes → dedicated scope → Add mapper, ajoutez :
- Un mapper User Property pour
id, avec le nom d'attribut SAMLhttp://schemas.microsoft.com/identity/claims/objectidentifier - Un mapper User Property pour
email, nom d'attributhttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress - Un mapper Group list, nom d'attribut
http://schemas.microsoft.com/ws/2008/06/identity/claims/groups
- Un mapper User Property pour
- Récupérez le certificat de signature du realm depuis Realm settings → Keys, et l'URL de connexion
https://<host>/realms/<realm>/protocol/saml.
Étape 3 — Terminer dans Vaks PM
| Champ | Valeur |
|---|---|
| URL de connexion IdP (entryPoint) | L'URL de connexion de l'étape 2. Doit être en HTTPS. |
| Certificat de signature IdP (X.509) | Utilisez Téléverser le fichier de certificat et sélectionnez le fichier téléchargé (.cer, .crt, .pem). |
| Rôle par défaut (JIT) | Rôle attribué à un utilisateur nouvellement créé ne correspondant à aucun mappage de groupe. |
| Utilisateur inconnu (aucun objectId correspondant) | Créer le compte automatiquement (JIT) (consomme un siège de licence) ou Refuser la connexion (ne pas consommer de siège). |
-----BEGIN CERTIFICATE-----, et les fournisseurs vous remettent un corps base64 nu. Le bouton de téléversement convertit ce que vous lui donnez — PEM, base64 brut ou binaire — alors que coller le corps base64 directement dans le champ est rejeté.
Étape 4 — Mapper les groupes aux rôles
Sous Mappages groupe → rôle, ajoutez une ligne par groupe. Sur Entra, la valeur est l'object ID du groupe ; sur les autres fournisseurs, c'est ce que votre attribute statement émet, généralement le nom du groupe.
- L'ordre fait la priorité — un utilisateur détient exactement un rôle d'organisation, et la première ligne correspondante en partant du haut l'emporte. La correspondance est une égalité de chaîne exacte.
- Aucune correspondance donne le rôle par défaut à un nouveau compte, et laisse intact le rôle d'un compte existant.
- Le fournisseur d'identité fait autorité sur les rôles rétrograde en outre au rôle par défaut, à chaque connexion, les utilisateurs ne correspondant à aucun mappage. Laissez la case décochée si vous attribuez les rôles à la main.
Un attribut de groupes vide ou absent est traité comme « inconnu » plutôt que comme « aucun groupe » : un attribut mal configuré ne peut donc pas rétrograder toute votre organisation. Le dernier administrateur global restant n'est jamais rétrogradé.
Étape 5 — Tester, puis activer
Pressez Tester sur la ligne du fournisseur, mais comprenez bien ce que cela fait : pour SAML, l'opération vérifie seulement qu'une URL de connexion est présente et que le certificat ressemble à du PEM valide. Elle ne contacte pas votre fournisseur et ne vérifie pas le certificat cryptographiquement. Un test réussi signifie que le formulaire est complet, rien de plus.
Le vrai test est une connexion. Cochez Activé (affiché sur l'écran de connexion), enregistrez, puis dans une fenêtre privée connectez-vous comme utilisateur pilote et vérifiez :
- L'utilisateur revient dans Vaks PM connecté.
- Son rôle dans Admin → Utilisateurs correspond au mappage attendu — ce qui prouve que l'attribut de groupes est bien arrivé.
- Une entrée
auth.sso.loginapparaît dans le journal d'audit.
Terminez la connexion en moins de 10 minutes ; la poignée de main est à usage unique et expire au bout de 600 secondes.
Dépannage
Les messages sont affichés dans la langue demandée par votre navigateur, l'utilisateur n'étant pas encore authentifié. Ils sont reproduits ci-dessous en français.
| Symptôme | Cause & correctif |
|---|---|
| Échec de validation de l'assertion SAML. | Le message fourre-tout, délibérément vague pour ne pas servir d'oracle de sondage. En pratique il s'agit d'une des quatre causes suivantes, par ordre de probabilité : le certificat ne correspond pas à celui qui signe réellement ; une dérive d'horloge d'un côté ou de l'autre ; l'audience n'est pas égale à l'entity ID du fournisseur de service ; ou le fournisseur chiffre l'assertion, ce qui n'est pas pris en charge. La raison réelle est dans les logs du conteneur api — lisez-les plutôt que de deviner. |
| Réponse SAML absente (SAMLResponse manquant). | Le fournisseur n'a rien posté d'exploitable, généralement parce que l'URL ACS pointe ailleurs ou que le binding n'est pas HTTP-POST. |
| Un compte avec cet email existe déjà mais n'est pas lié à cette identité IdP (objectId)… | Un compte porte cet email mais n'a jamais été lié. Si le message apparaît pour chaque utilisateur, votre fournisseur n'émet presque certainement pas l'attribut d'identifiant d'objet, et l'email sert donc de clé de compte. Corrigez l'attribute statement. |
| Aucun compte ne correspond à cette identité (objectId) et la création automatique est désactivée. | La création automatique est désactivée et aucun compte ne correspond. Provisionnez d'abord le compte, ou changez le réglage. |
| L'assertion SAML ne contient pas d'identifiant (objectId/nameID) ou d'email exploitable. | Ni identifiant d'objet, ni NameID ou email exploitable ne sont arrivés. Vérifiez l'attribute statement et le format de NameID. |
| État de session SAML invalide ou expiré. | Plus de 10 minutes se sont écoulées, l'URL a été rejouée, ou Redis est hors service. Notez que la connexion initiée par le fournisseur n'est pas prise en charge — les utilisateurs doivent partir de la page de connexion Vaks PM. |
| Provider SAML incomplet (entryPoint / certificat IdP manquant). | Activé alors qu'un champ manquait. Rouvrez-le et complétez-le. |
| Ça marchait, puis ça s'est arrêté pour tout le monde le même jour | Le fournisseur a effectué la rotation de son certificat de signature. Téléchargez le nouveau et téléversez-le ici. Fréquent avec AD FS, dont le renouvellement automatique est actif par défaut. |
| Échecs intermittents, sans logique apparente | Dérive d'horloge au-delà de la tolérance de 30 secondes. Le log du conteneur api nomme explicitement ce cas — cherchez CLOCK SKEW between IdP and this host, qui affiche aussi l'heure du serveur et la tolérance en vigueur. Vérifiez NTP sur le fournisseur d'identité et sur chaque hôte Vaks PM avant de soupçonner le certificat. |
| Tout le monde atterrit sur le rôle par défaut | L'attribut de groupes n'arrive pas sous l'URI exact attendu. Il n'existe aucun repli pour lui en SAML. |
Ce qui est journalisé
Sous Admin → Sécurité & Conformité → Journal d'audit : auth.sso.login à chaque connexion fédérée (avec le protocole et l'indication de la création éventuelle du compte), auth.sso.failure avec le motif de refus, user.provisioned.sso à la création d'un compte, et idp.created / idp.updated / idp.deleted pour les changements de configuration, le tout en sévérité critique.
Les échecs de validation d'assertion sont journalisés avec leur cause réelle dans le conteneur api, jamais dans le navigateur.
À lire aussi : authentification unique OIDC, préférable quand elle est disponible · provisioning SCIM · toutes les intégrations.