Skip to content

Authentification SSO — A1Connect ↔ Inspire V2

Vue d'ensemble

L'authentification repose sur deux JWT distincts qui ne doivent pas être confondus :

JWT A1Connect (sessionJwt) JWT Inspire (loginToken)
Signé par A1Connect (clé privée A1C) Inspire V2 (sa propre clé privée)
Algorithme RS256 RS256
Durée courte / session 30 jours
Usage handshake SSO uniquement toutes les requêtes API Inspire
Transmis via Authorization: Bearer (A1C API) Authorization: Bearer (Inspire API)

Il n'y a pas de cookie. Les deux applications utilisent exclusivement des Bearer tokens.


Flux SSO complet (navigateur — production)

1. Frontend Inspire
   └─ GET /auth-jwt/sso-jwt
      → Inspire génère un JWT signé (payload: redirect_uri, profile_token)
      → Renvoie ce JWT au frontend

2. Frontend
   └─ Redirige le navigateur vers A1Connect avec ce JWT en paramètre

3. Utilisateur s'authentifie sur A1Connect (login/mdp)

4. A1Connect
   └─ POST /auth-jwt/sso-redirect  (sur l'API Inspire)
      body: { profile_jwt: "<jwt signé par A1C>" }
      → Inspire vérifie la signature avec la clé publique A1C (SSO_PUBLIC_KEY)
      → Find or create user en base (par ssoId puis par email)
      → Génère son propre JWT Inspire (30j, payload: { id, username })
      → HTTP 302 → FRONTEND_URL/auth/callback?loginToken=<jwt_inspire>&isSignUp=...

5. Frontend
   └─ Stocke loginToken
   └─ Envoie Authorization: Bearer <loginToken> sur toutes les requêtes Inspire

Tester avec Bruno

Option A — Login direct (recommandé en dev)

Inspire expose un endpoint username/password pour le développement :

POST http://localhost:3236/auth-jwt/login
body: { "username": "...", "password": "..." }
→ 200 { "token": "<jwt_inspire>" }

→ Utiliser la request Auth > Login dans la collection Bruno d'Inspire.
Le token est auto-sauvegardé dans {{token}}.

Créer un utilisateur de dev : ne pas insérer en base directement — le mot de passe doit être bcrypté. Passer par l'endpoint register :

POST http://localhost:3236/auth-jwt/register
body: { "username": "dev@example.com", "password": "Test1234!" }

Les users créés via register ont activated = false par défaut. Pour contourner sans attendre l'email :

UPDATE "user-jwt" SET activated = true WHERE username = 'dev@example.com';

Note sur le nom de la table user-jwt : c'est la table des utilisateurs natifs d'Inspire (ceux qui s'authentifient en local par username/password), pas une table de tokens JWT. Le nom vient du module auth-jwt. Les users SSO (qui passent par A1Connect) sont dans la table users.

Option B — Simuler le flux SSO complet

Utile pour tester le comportement de sso-redirect (find-or-create, isSignUp, etc.).

Étape 1 — S'authentifier sur A1Connect (auth/01-login) → sauvegarde {{sessionJwt}}

Étape 2 — Générer un profile_jwt (auth/04-profile-jwt) → sauvegarde {{profileJwt}}
Le body doit contenir "audience": "inspire".

Étape 3 — Appeler le sso-redirect d'Inspire :

POST http://localhost:3236/auth-jwt/sso-redirect
body: { "profile_jwt": "{{profileJwt}}" }

→ Inspire retourne un HTTP 302 vers FRONTEND_URL/auth/callback?loginToken=<jwt>
→ Extraire le loginToken de l'URL de redirection et l'utiliser comme Bearer.


Variables d'environnement concernées

A1Connect (Bruno)

  • sessionJwt — JWT A1C, obtenu via auth/01-login
  • profileJwt — JWT de profil A1C, obtenu via auth/04-profile-jwt

Inspire V2 (Bruno, collection séparée)

  • token — JWT Inspire (30j), obtenu via auth/login ou extrait du callback SSO

Configuration serveur

Variable A1Connect Inspire V2
JWT_PRIVATE_KEY Signe les profile_jwt Signe les loginToken
JWT_PUBLIC_KEY Valide ses propres loginToken
SSO_PUBLIC_KEY Valide les profile_jwt reçus d'A1C
SSO_ISSUER / SSO_AUDIENCE Utilisés lors de la création du JWT SSO