inrae-umrh/iam-bundle

Bundle Symfony pour l'authentification OAuth2/OIDC avec le système IAM de l'INRAE

Maintainers

Package info

forge.inrae.fr/symfony_iam/iam-symfony-bundle

Type:symfony-bundle

pkg:composer/inrae-umrh/iam-bundle

Statistics

Installs: 9

Dependents: 0

Suggesters: 0

v1.0.3 2026-04-24 07:07 UTC

This package is auto-updated.

Last update: 2026-04-24 07:48:25 UTC


README

Bundle Symfony pour l'authentification OAuth2/OIDC avec le système IAM de l'INRAE.

Ce bundle fournit une intégration facile avec l'authentification INRAE tout en maintenant la rétrocompatibilité avec l'ancienne méthode d'utilisation.

Installation

composer require inrae-umrh/iam-bundle

Ou ajoutez le bundle à votre composer.json :

{
    "require": {
        "inrae-umrh/iam-bundle": "^1.0.0"
    }
}

Installation automatique

Le bundle s'installe automatiquement lors de l'exécution de composer install ou composer update. Le script d'installation effectue les actions suivantes :

  • ✓ Ajoute le bundle à config/bundles.php
  • ✓ Crée le fichier config/packages/inrae_iam.yaml
  • ✓ Ajoute les variables d'environnement au .env

Vous n'avez aucune configuration manuelle à faire après l'installation du bundle.

Configuration

Le script d'installation a automatiquement créé le fichier config/packages/inrae_iam.yaml et ajouté les variables d'environnement à votre .env.

Il ne vous reste qu'à configurer les valeurs dans votre fichier .env :

AUTH_URL="https://authentification.inrae.fr/.well-known/openid-configuration"
CLIENT_ID="votre_client_id"
CLIENT_SECRET="votre_client_secret"
REDIRECT_URI="https://votre-domaine.com/login"
USER_INFO_ENDPOINT="https://authentification.inrae.fr/oauth2/userinfo"

Utilisation

Mode rétrocompatible (code existant)

Si vous utilisiez déjà l'ancienne méthode avec new Authenticator(...), votre code continue de fonctionner sans modification :

use InraeIamBundle\Authenticator;

$auth = new Authenticator(
    $this->getParameter('app.authurl'),
    $this->getParameter('app.clientid'),
    $this->getParameter('app.clientsecret'),
    $this->getParameter('app.redirecturi'),
);

if (isset($_GET['code'])) {
    if ($auth->connexion() && $auth->isActive()) {
        $tokenData = $auth->getToken();
        $userDetails = $auth->getUserDetails();
        // ... votre logique existante
    }
} else {
    $auth->redirect(['customScope']);
}

Mode moderne (injection de dépendances)

Utilisez l'injection de dépendances pour une intégration Symfony plus propre :

use InraeIamBundle\Authenticator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class LoginController extends AbstractController
{
    #[Route('/login', name: 'login')]
    public function login(Authenticator $auth): Response
    {
        if ($auth->getCode()) {
            if ($auth->connexion() && $auth->isActive()) {
                $tokenData = $auth->getToken();
                $userDetails = $auth->getUserDetails();
                // ... votre logique avec les données utilisateur
                return $this->redirectToRoute('home');
            }
        }
        
        // Redirection vers l'IAM
        $auth->redirect(['customScope']);
    }
}

Ou utilisez la méthode authenticate() pour une approche encore plus simple :

$result = $auth->authenticate();

if ($result['success']) {
    $tokenData = $result['token'];
    $userDetails = $result['user_details'];
    // ... votre logique
    return $this->redirectToRoute('home');
}

$auth->redirect(['customScope']);

Mode avancé (avec IamUserService)

Le service IamUserService simplifie la gestion complète du flux OAuth2 et la création d'utilisateurs :

Configuration du service :

Dans config/services.yaml, configurez la classe utilisateur :

services:
    InraeIamBundle\Service\IamUserService:
        arguments:
            $authenticator: '@InraeIamBundle\Authenticator'
            $entityManager: '@doctrine.orm.entity_manager'
            $tokenStorage: '@security.token_storage'
            $userClass: 'App\Entity\Utilisateur'

Utilisation dans un controller :

use InraeIamBundle\Service\IamUserService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class LoginController extends AbstractController
{
    #[Route('/login', name: 'login')]
    public function login(IamUserService $iamService): Response
    {
        if (isset($_GET['code'])) {
            $result = $iamService->handleCallback();
            
            if ($result['success']) {
                return $this->redirectToRoute('home');
            }
            
            return $this->render('login.html.twig', [
                'error' => $result['error']
            ]);
        }
        
        $iamService->redirectToAuth(['customScope']);
    }
}

API exposée

Authenticator

Classe principale rétrocompatible pour l'authentification IAM.

Constructeur :

__construct(string $authurl, string $client_id, string $client_secret, string $redirect_uri)

Méthodes :

  • getCode(): ?string - Retourne le code d'autorisation depuis la requête
  • authenticate(): array - Gère le flux OAuth2 complet (callback + validation). Retourne ['success' => bool, 'token' => ?array, 'user_details' => ?array, 'error' => ?string]
  • connexion(): bool - Traite le callback OAuth2
  • isActive(): bool - Vérifie si le token est actif
  • getToken(): ?array - Retourne les données du token
  • getUserDetails(): ?array - Retourne les informations utilisateur
  • redirect(array $customScopes = []): void - Redirige vers l'endpoint d'autorisation
  • http(string $url, array|false $params = false): ?array - Effectue une requête HTTP
  • infoUser(string $url, string $token): ?array - Récupère les infos utilisateur

IamUserService

Service helper pour simplifier l'intégration avec Symfony Security.

Méthodes :

  • redirectToAuth(array $customScopes = []): void - Redirige vers l'authentification IAM
  • handleCallback(): array - Traite le callback et authentifie l'utilisateur
  • setUserConfig(EntityManagerInterface $entityManager, string $userClass): void - Configure la gestion des utilisateurs
  • setTokenStorage(TokenStorageInterface $tokenStorage): void - Configure le token storage

Migration depuis l'ancienne méthode

Si vous utilisiez l'ancienne méthode, vous avez 3 options :

Option 1 : Aucun changement (rétrocompatibilité)

Votre code existant fonctionne tel quel. Il suffit d'installer le bundle et de configurer les paramètres.

Option 2 : Injection de dépendances simple

Remplacez l'instanciation manuelle par l'injection de dépendances :

// Avant
$auth = new Authenticator(
    $this->getParameter('app.authurl'),
    $this->getParameter('app.clientid'),
    // ...
);

// Après
public function login(Authenticator $auth): Response
{
    // Utilisez $auth directement
}

Option 3 : Utilisation de IamUserService

Simplifiez votre controller en utilisant le service helper :

// Avant
if ($auth->connexion() && $auth->isActive()) {
    $tokenData = $auth->getToken();
    $username = $tokenData['sub'];
    $user = $entityManager->getRepository(Utilisateur::class)->findOneBy(['username' => $username]);
    if (null === $user) {
        $infos = $auth->getUserDetails();
        $user = new Utilisateur();
        // ... création utilisateur
    }
    $token = new UsernamePasswordToken($user, 'main', $user->getRoles());
    $tokenStorage->setToken($token);
}

// Après
$result = $iamService->handleCallback();
if ($result['success']) {
    return $this->redirectToRoute('home');
}

Structure du bundle

InraeIamBundle/
├── InraeIamBundle.php              # Classe principale du bundle
├── Authenticator.php                # Classe d'authentification rétrocompatible
├── DependencyInjection/
│   ├── Configuration.php            # Configuration YAML du bundle
│   └── InraeIamExtension.php        # Extension du conteneur DI
├── Resources/
│   └── config/
│       └── services.yaml            # Définition des services
└── Service/
    └── IamUserService.php           # Service helper pour Symfony Security

Licence

Ce bundle est développé pour l'INRAE.