Aller au contenu

Guide d'intégration

Ce guide décrit ce que vous devez fournir et mettre en œuvre pour intégrer votre ressource à ProxyNinja : la configuration d’authentification (OIDC, SAML2 ou CAS3), le point d’entrée fonctionnel (vérification de session), et des exemples de code par stack (PHP, Laravel, Node), y compris la déconnexion et le rafraîchissement des jetons.

Élément OIDC SAML2 CAS3
Identifiant client client_id + client_secret entityID du SP + certificat nom de service
URL de retour redirect_uri (callback) ACS (Assertion Consumer Service) service URL
URL de login (point d’entrée)
URL de logout (back-channel / SLO)

Vous fournissez ces éléments pour la préproduction et la production. Voir le questionnaire, sections B et F.

Rappel des bases realm (<EDITEUR> = votre realm = le slug de votre tenant) :

Environnement Modèle de déploiement Base realm
Préproduction instance partagée https://preprod-proxy.gar.ninja/realms/<EDITEUR>
Production instance dédiée par éditeur https://<EDITEUR>-auth.proxyninja.fr/realms/<EDITEUR>

ProxyNinja est l’OP (OpenID Provider). Tout se découvre depuis le document .well-knownne codez pas les endpoints en dur, lisez-les depuis la découverte.

  • Issuer : https://<EDITEUR>-auth.proxyninja.fr/realms/<EDITEUR>
  • Découverte : …/realms/<EDITEUR>/.well-known/openid-configuration
  • Endpoints (exposés par la découverte) :
    • authorization_endpoint : …/protocol/openid-connect/auth
    • token_endpoint : …/protocol/openid-connect/token
    • userinfo_endpoint : …/protocol/openid-connect/userinfo
    • end_session_endpoint : …/protocol/openid-connect/logout
    • jwks_uri : …/protocol/openid-connect/certs
  • Flow : Authorization Code + PKCE (S256).
  • Scopes : openid (obligatoire) profile email, plus les scopes d’attributs établissement si activés sur votre realm.
  • Authentification client : client_secret_basic (ou client_secret_post).

ProxyNinja est l’IdP ; votre application est le SP.

  • Métadonnées IdP (à consommer) : https://<EDITEUR>-auth.proxyninja.fr/realms/<EDITEUR>/protocol/saml/descriptor
  • SSO / SLO : https://<EDITEUR>-auth.proxyninja.fr/realms/<EDITEUR>/protocol/saml
  • À fournir (métadonnées SP) : entityID, URL ACS (binding HTTP-POST), URL SLO, format de NameID souhaité, et le certificat de signature du SP.
  • Indiquez si vous exigez des assertions signées/chiffrées (recommandé : assertions signées).

ProxyNinja expose le protocole CAS (extension CAS de Keycloak). Vous agissez en client CAS.

  • Base CAS : https://<EDITEUR>-auth.proxyninja.fr/realms/<EDITEUR>/protocol/cas
    • login : …/protocol/cas/login?service=<votre-service>
    • validate (CAS3, avec attributs) : …/protocol/cas/p3/serviceValidate
    • logout : …/protocol/cas/logout
  • À fournir : l’URL service (votre point d’entrée) et l’URL de logout pour la propagation.

Le cœur de l’intégration côté éditeur est un point d’entrée qui implémente une seule décision :

Requête entrante sur le point d'entrée
Ai-je une session locale valide ?
┌────┴─────┐
OUI NON
│ │
▼ ▼
Servir la Demander l'authentification à ProxyNinja
ressource (OIDC /authorize · SAML AuthnRequest · CAS /login)
Retour (code / ticket) → échange jetons → récupérer les attributs
Créer la session locale → servir la ressource

Comme l’utilisateur arrive déjà authentifié depuis le médiacentre, la demande à ProxyNinja est en général transparente (pas de re-saisie). Voir le parcours de bout en bout.

Bibliothèques recommandées (voir le récapitulatif en bas de page) :

OIDC — point d’entrée + récupération des attributs

Section intitulée « OIDC — point d’entrée + récupération des attributs »
Fenêtre de terminal
composer require jumbojett/openid-connect-php
<?php
require 'vendor/autoload.php';
use Jumbojett\OpenIDConnectClient;
session_start();
// --- Point d'entrée : ai-je une session locale ? ---
if (!empty($_SESSION['user'])) {
render_resource($_SESSION['user']); // OUI → on sert la ressource
exit;
}
// NON → on demande l'identité à ProxyNinja.
$oidc = new OpenIDConnectClient(
'https://<EDITEUR>-auth.proxyninja.fr/realms/<EDITEUR>', // issuer (sans slash final)
'votre-client-id',
'votre-client-secret'
);
$oidc->setRedirectURL('https://votre-ressource.fr/callback');
$oidc->addScope(['openid', 'profile', 'email']);
$oidc->setCodeChallengeMethod('S256'); // PKCE recommandé
$oidc->authenticate(); // redirige vers ProxyNinja, puis revient ici
$claims = $oidc->requestUserInfo(); // récupération des attributs (/userinfo)
$_SESSION['user'] = (array) $claims;
$_SESSION['id_token'] = $oidc->getIdToken();
$_SESSION['access_token'] = $oidc->getAccessToken();
$_SESSION['refresh_token'] = $oidc->getRefreshToken();
render_resource($_SESSION['user']);

ProxyNinja notifie votre ressource lorsqu’une session doit être fermée (POST d’un logout_token JWT). Votre endpoint doit : (1) valider le logout_token (signature via le jwks_uri du realm), (2) extraire sub et/ou sid, (3) détruire la session locale correspondante — en quelques secondes, sans attendre l’expiration d’un jeton.

POST /backchannel_logout HTTP/1.1
Host: votre-ressource.fr
Content-Type: application/x-www-form-urlencoded
logout_token=eyJhbGci....eyJpc3Mi....T3BlbklE..
<?php
require 'vendor/autoload.php';
use Jumbojett\OpenIDConnectClient;
// Endpoint POST /backchannel_logout
$logoutToken = $_POST['logout_token'] ?? '';
$oidc = new OpenIDConnectClient(
'https://<EDITEUR>-auth.proxyninja.fr/realms/<EDITEUR>',
'votre-client-id',
'votre-client-secret'
);
// Valide la signature + les claims (iss, aud, events, sid/sub) via le JWKS du realm
if ($oidc->verifyLogoutToken($logoutToken)) {
$sid = $oidc->getSidFromBackChannel(); // ou claim `sub`
destroy_local_sessions_for($sid); // votre logique (table sid → session)
http_response_code(200);
} else {
http_response_code(400);
}

Rafraîchissez l’access_token avant son expiration (avec le refresh_token) plutôt que de forcer une reconnexion.

// Avant un appel protégé, si l'access_token est proche de l'expiration :
$oidc->refreshToken($_SESSION['refresh_token']);
$_SESSION['access_token'] = $oidc->getAccessToken();
$_SESSION['refresh_token'] = $oidc->getRefreshToken(); // rotation éventuelle
Protocole PHP Laravel Node.js
OIDC jumbojett/openid-connect-php Socialite + socialiteproviders/keycloak (ou Kovah/laravel-socialite-oidc) openid-client (+ openid-client/passport)
SAML2 onelogin/php-saml (ou simpleSAMLphp en mode SP) aacotroneo/laravel-saml2 (basé sur OneLogin) @node-saml/passport-saml (ou samlify)
CAS3 apereo/phpCAS apereo/phpCAS (intégré manuellement) connect-cas2 / client CAS dédié
  1. Stockage sécurisé des jetons : jamais en clair ; cookies de session serveur (HttpOnly, Secure, SameSite) ou store serveur.
  2. PKCE (S256) systématique sur le flow OIDC Authorization Code.
  3. Découverte .well-known : lisez les endpoints depuis la découverte, ne les codez pas en dur.
  4. Renouvellement automatique : rafraîchissez avant expiration.
  5. Déconnexion en quelques secondes : propagez le back-channel logout immédiatement ; n’attendez jamais l’expiration d’un jeton.
  6. Validez toujours la signature des jetons (id_token, logout_token) via le jwks_uri du realm.