keycloak-auth / symfony-bundle
Modern Symfony bundle for Keycloak JWT authentication
Package info
github.com/emopro-project/symfony-keycloak-bundle
Type:symfony-bundle
pkg:composer/keycloak-auth/symfony-bundle
Requires
- php: >=8.1
- firebase/php-jwt: ^6.11
- lcobucci/jwt: ^4.0
- promphp/prometheus_client_php: ^2.14
- symfony/expression-language: ^6.4 || ^7.0
- symfony/framework-bundle: ^6.4 || ^7.0
- symfony/http-client: ^6.4 || ^7.0
- symfony/rate-limiter: ^6.4 || ^7.0
- symfony/routing: ^6.4 || ^7.0
- symfony/security-bundle: ^6.4 || ^7.0
- web-token/jwt-key-mgmt: ^3.4
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpstan/phpstan-symfony: ^2.0
- phpunit/phpunit: ^10 || ^11
- symfony/phpunit-bridge: ^6.4 || ^7.0
Conflicts
README
Bundle Symfony pour intégrer Keycloak comme fournisseur d’identité (IAM) et gérer :
- 🔐 L’authentification des utilisateurs (login / mot de passe)
- 🤖 L’authentification API ↔ API via
client_credentials - 🏢 Des architectures d’entreprise avec IAM centralisé
🚀 Installation
Ajoutez le bundle dans votre application Symfony.
1. Activer le bundle
Dans config/bundles.php :
return [ // ... KeycloakAuthBundle\KeycloakBundle::class => ['all' => true], ];
⚙️ Configuration de base
2. Fichier de configuration
Créez le fichier :
config/packages/keycloak.yaml
Contenu :
keycloak: realm: "votre-realm-keycloak" client_id: "keycloak-client-id" client_secret: "keycloak-client-secret" base_url: "http://keycloak:8080" # URL de votre serveur Keycloak redirect_uri: "http://localhost:8085/login/check" # URI déclarée dans Keycloak
🌐 Authentification Web (utilisateur humain)
Configuration du client Keycloak :
Paramètres importants
-
Root URL
http://localhost:8085 -
Valid Redirect URIs
http://localhost:8085/* -
Valid Post Logout Redirect URIs
http://localhost:8085/login/check
Options à activer
- Standard Flow ✅
- Direct Access Grants ✅ (login + mot de passe)
🔑 Authentification API ↔ API (Client Credentials)
Cas d’usage
- Aucun utilisateur humain
- Une application appelle une autre application
- L’identité = application
👉 Le flow client_credentials est le plus adapté
🧠 Exemple de cas réel (Entreprise)
Contexte
- ERP
- CRM
- Facturation
- RH
- IAM centralisé : Keycloak
Scénario
- Le service Facturation appelle le CRM
- Aucun utilisateur connecté
- Authentification basée sur l’application
✅ client_credentials
🧩 Configuration Keycloak – Client API
Settings
- Client Authentication : Enabled ✅
- Service Accounts Roles : Enabled ✅
- Standard Flow : Enabled ✅
Roles
realm-management- ou
manage-clients
Mappers
- Mapper les roles dans le token JWT
🧪 Exemple d’utilisation dans Symfony
Injection des cas d’usage
use KeycloakAuthBundle\Application\UseCase\GetClientCredentialsToken; use KeycloakAuthBundle\Application\UseCase\AuthenticateUser;
Contrôleur d’exemple
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use KeycloakAuthBundle\Application\UseCase\GetClientCredentialsToken; use KeycloakAuthBundle\Application\UseCase\AuthenticateUser; class TestController extends AbstractController { public function __construct( private readonly GetClientCredentialsToken $getClientCredential, private AuthenticateUser $authenticateUser ) {} #[Route("/")] public function test(Request $request): JsonResponse { $token = $this->getClientCredential->execute(); if ($token) { $user = $this->authenticateUser->execute($token); } return $this->json([ 'token' => $token, 'decoded' => $user->toArray() ?? null, ]); } }
🔐 Sécurité & bonnes pratiques
- Ne jamais exposer le
client_secret - Utiliser HTTPS en production
- Limiter les rôles accordés aux services
- Vérifier les audiences (
aud) dans les tokens
📌 Résumé des flows supportés
| Flow | Usage | Activer dans Keycloak |
|---|---|---|
authorization_code |
Login utilisateur | Standard Flow ✅ |
direct_access_grants |
Login / mot de passe | Direct Access Grants ✅ |
client_credentials |
API ↔ API | Service Accounts Roles ✅ |
📄 Licence
MIT
✨ Bundle prêt pour des architectures modernes, sécurisées et orientées microservices.
🎯 1. Sécurité (raison n°1)
Dans ton contexte (Keycloak, JWT, login, token, JWKS…), le RateLimiter protège contre :
🔥 Attaques classiques
Brute-force login
Flood sur /token
Abus du refresh token
Enumeration d’utilisateurs
DoS applicatif léger