Single Sign-On
Chaque application Inklura — la console, SMS Designer, SEO, Mail, POS, support — partage une connexion unique. Le SSO fonctionne grâce à deux mécanismes coopérants :
- OIDC PKCE — chaque application authentifie les utilisateurs contre le fournisseur d'identité partagé, et la session propre à l'IdP rend les connexions suivantes silencieuses.
- Un token de transfert console→app — pour lancer silencieusement un utilisateur de la console déjà authentifié dans une application sœur (utilisé lors de l'embarquement).
Pour la vue d'ensemble de l'authentification (cookies de session, JWT Bearer, magic links), voir Authentification.
Mécanisme 1 — OIDC PKCE par application
Le fournisseur d'identité est auth.1clic.pro. Chaque application
*.inklura.fr est son propre client OIDC PKCE (S256) public — un client
public sans client secret :
- par ex. client id
smsdesigner-prism, redirecthttps://smsdesigner.inklura.fr/auth/callback - ou le client de realm partagé
inklura-admin, utilisé par seo + pos
Scopes : openid profile email offline_access.
Cookies de session de portée hôte
Après l'aller-retour OIDC, chaque application génère son propre cookie de session de portée hôte :
Set-Cookie: <session>; Path=/; SameSite=Lax; Secure
Notez qu'il n'y a aucun attribut Domain= — le cookie est cloisonné à cet
unique hôte, pas partagé entre sous-domaines.
Pourquoi la connexion reste silencieuse entre sous-domaines
Les utilisateurs semblent « connectés partout », mais pas parce qu'un cookie
est partagé. Chaque application a son propre cookie de portée hôte. Ce qui est
partagé, c'est la session propre à l'IdP sur auth.1clic.pro : quand un
utilisateur déjà authentifié visite une seconde application, l'aller-retour PKCE
de cette application se termine silencieusement au niveau de l'IdP (aucune
ressaisie de mot de passe), et l'application génère son cookie local.
app B : pas de cookie local ──> redirection vers auth.1clic.pro
l'IdP a déjà une session ──> autorisation silencieuse ──> /auth/callback
app B génère son PROPRE cookie de portée hôte
Précision sur node:crypto. L'isolat V8 de PRISM propose des stubs pour
node:crypto et crypto.subtle.digest, de sorte que SHA-256 / HMAC sont
implémentés à la main en pur JS dans le oidc.ts de chaque application. Par
défaut, l'id_token est décodé, pas vérifié cryptographiquement — l'ancre de
confiance est l'échange de token protégé par TLS avec l'IdP. Une vérification
RS256 via JWKS optionnelle est disponible derrière un flag.
Mécanisme 2 — token de transfert console→app
Pour déposer silencieusement un utilisateur de la console déjà authentifié dans une application sœur (par exemple à l'intérieur d'un iframe), la console génère un token signé à courte durée et redirige le navigateur vers l'application cible, qui le vérifie et génère sa propre session locale.
Format du token
b64url(JSON(payload)) + "." + b64url(hmacSha256(INKLURA_SSO_SECRET, b64payload))
- Le HMAC est calculé sur le payload encodé en b64url en utilisant
INKLURA_SSO_SECRET. - TTL : 120 secondes.
Payload :
{ "sub": "…", "email": "…", "name": "…", "tenant_id": "…", "aud": "…", "iat": 0, "exp": 0 }
Le claim aud est le client id OIDC de l'application cible. Parce que la
signature couvre aud, le token n'est pas rejouable sur une autre application
— un token généré pour l'application A échoue à la vérification d'audience de
l'application B.
La route de génération
GET /api/manage/designer-sso?app=<key>&next=<path>&embed=1
- Protégée par le contrôle d'accès propre à la console.
- Ne porte que l'identité de l'appelant lui-même (il ne peut pas se faire passer pour un autre utilisateur).
- Résout l'application sœur sur le même domaine enregistrable et redirige en 302 vers celle-ci avec le token.
La route d'atterrissage (côté application)
L'application cible expose une route d'atterrissage qui consomme le token :
| Route d'atterrissage | Applications |
|---|---|
/auth/sso |
mail, sms, ads |
/auth/manage-sso |
seo, pos, support |
La route d'atterrissage :
- Vérifie le HMAC.
- Contrôle
exp(non expiré). - Affirme
aud === CLIENT_ID(cette application est bien l'audience visée). - Génère la session locale et redirige vers
next.
console (authentifiée) ──GET /api/manage/designer-sso?app=mail&next=/inbox&embed=1
génère le token (aud = client id de mail, TTL 120s)
302 ──> https://mail.inklura.fr/auth/sso?token=…&next=/inbox
vérifie HMAC + exp + aud === CLIENT_ID
génère la session locale ──> 302 /inbox
Même site vs nouvel onglet
Quand la console lance une application sœur de cette façon, les applications du même site sont embarquées dans un iframe ; les applications d'un site différent sont lancées dans un nouvel onglet. Les règles de framing qui rendent possible l'embarquement même-site sont couvertes dans Embarquement en iframe.
Voir aussi
- Authentification — sessions, JWT Bearer, OIDC, magic links
- Embarquement en iframe — CSP et embarquement d'une application sœur