PHPackages                             zepekegno/keycloak-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. zepekegno/keycloak-bundle

ActiveSymfony-bundle[Authentication &amp; Authorization](/categories/authentication)

zepekegno/keycloak-bundle
=========================

Symfony bundle for Keycloak integration (OIDC, SSO, user management)

v1.0.0(8mo ago)11MITPHPPHP &gt;=8.0

Since Aug 20Pushed 8mo agoCompare

[ Source](https://github.com/zepekegno224/keycloakBundle)[ Packagist](https://packagist.org/packages/zepekegno/keycloak-bundle)[ Docs](https://github.com/zepekegno224/keycloakBundle)[ RSS](/packages/zepekegno-keycloak-bundle/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (10)Versions (4)Used By (0)

Complete Documentation for Keycloak Bundle for Symfony
======================================================

[](#complete-documentation-for-keycloak-bundle-for-symfony)

Table of Contents
-----------------

[](#table-of-contents)

1. [Overview](#overview)
2. [Bundle Architecture](#bundle-architecture)
3. [Installation and Configuration](#installation-and-configuration)
4. [Core Services](#core-services)
5. [Security System](#security-system)
6. [Controllers and Routes](#controllers-and-routes)
7. [Practical Usage](#practical-usage)
8. [Advanced Configuration](#advanced-configuration)
9. [Integration Examples](#integration-examples)
10. [Troubleshooting](#troubleshooting)

Overview
--------

[](#overview)

The **Keycloak Bundle for Symfony** (`Zepekegno\KeycloakBundle`) is a complete Keycloak integration solution that provides:

### Core Features

[](#core-features)

- ✅ **OIDC/OAuth 2.0 Authentication** with PKCE support
- ✅ **JWT Token Validation** with signature verification
- ✅ **User Management** via Keycloak Admin API
- ✅ **Automatic Email Verification** during registration
- ✅ **SSO (Single Sign-On)** multi-platform
- ✅ **Automatic Token Refresh**
- ✅ **Custom Attributes** to identify platforms
- ✅ **Role Management** (realm and client)
- ✅ **Global Logout** Keycloak

### Use Cases

[](#use-cases)

- Web applications with centralized authentication
- JWT-secured REST APIs
- Microservices architecture with SSO
- Multi-platform applications (web, mobile, desktop)
- Systems requiring centralized user management

Requirements
------------

[](#requirements)

- PHP: &gt;= 8.0 (bundle minimum); examples in this repository run with PHP &gt;= 8.2 (Symfony 7.3.\*)
- Symfony components (required by the bundle):
    - symfony/framework-bundle: &gt;=6.0
    - symfony/security-bundle: &gt;=6.0
    - symfony/http-client: &gt;=6.0
- JWT library:
    - firebase/php-jwt: ^6.0
- Notes:
    - Typical Symfony apps also have ext-ctype and ext-iconv enabled.
    - The sample applications in this repository use Symfony 7.3.\* and PHP 8.2.

Minimal install in a Symfony project:

```
composer require symfony/framework-bundle symfony/security-bundle symfony/http-client firebase/php-jwt
```

### File Structure

[](#file-structure)

```
KeycloakBundle/
├── config/
│   ├── routes.yaml          # Routes d'authentification
│   └── services.yaml        # Configuration des services
├── src/
│   ├── Controller/
│   │   └── AuthController.php
│   ├── DependencyInjection/
│   │   ├── Configuration.php
│   │   └── KeycloakExtension.php
│   ├── Security/
│   │   ├── JwtAuthenticator.php
│   │   ├── KeycloakAuthenticator.php
│   │   ├── KeycloakUser.php
│   │   └── KeycloakUserProvider.php
│   ├── Service/
│   │   ├── KeycloakAdminService.php
│   │   ├── OIDCService.php
│   │   └── TokenRefreshService.php
│   └── KeycloakBundle.php
└── translations/
    ├── messages.en.yaml
    └── messages.fr.yaml

```

### Authentication Flow

[](#authentication-flow)

 ```
sequenceDiagram
    participant U as User
    participant A as Application
    participant K as Keycloak
    participant B as Bundle

    U->>A: Login request
    A->>B: Generate OIDC URL
    B->>K: Redirect with PKCE
    K->>U: Login page
    U->>K: Enter credentials
    K->>A: Authorization code
    A->>B: Exchange code → tokens
    B->>K: Validate tokens
    B->>A: Authenticated user
```

      Loading Installation and Configuration
------------------------------

[](#installation-and-configuration)

### 1. Installation

[](#1-installation)

```
composer require zepekegno/keycloak-bundle
```

### 2. Bundle Activation

[](#2-bundle-activation)

```
// config/bundles.php
return [
    // ... autres bundles
    Zepekegno\KeycloakBundle\KeycloakBundle::class => ['all' => true],
];
```

### 3. Bundle Configuration

[](#3-bundle-configuration)

```
# config/packages/keycloak.yaml
keycloak:
    # Paramètres requis
    base_url: '%env(KEYCLOAK_BASE_URL)%'              # Keycloak server base URL
    realm: '%env(KEYCLOAK_REALM)%'                    # Realm name Keycloak
    client_id: '%env(KEYCLOAK_CLIENT_ID)%'            # Public client ID for OIDC
    client_secret: '%env(KEYCLOAK_CLIENT_SECRET)%'    # Client Secret for OIDC
    admin_client_id: '%env(KEYCLOAK_ADMIN_CLIENT_ID)%'        # Admin Client ID for Admin API
    admin_client_secret: '%env(KEYCLOAK_ADMIN_CLIENT_SECRET)%' # Admin Client Secret for Admin API
    public_key: '%env(KEYCLOAK_PUBLIC_KEY)%'          # Realm public key for JWT verification
    scope: 'openid profile email'
    algorithm: RS256				      # JWT signing algorithm

    # Paramètres optionnels
    verify_token: true                                # Enable JWT signature verification (default: true)
    user_provider_service: null                       # Custom User Provider Service ID (défaut: null)
    redirect_routes:                                  # Role-based redirection after authentication
        ROLE_ADMIN: 'admin_dashboard'
        ROLE_USER: 'user_dashboard'
        default: '/'
```

### 4. Environment Variables

[](#4-environment-variables)

```
# .env
# Keycloak server configuration
KEYCLOAK_BASE_URL=https://your-keycloak.example.com
KEYCLOAK_REALM=your-realm-name

# OIDC Client (user authentication)
KEYCLOAK_CLIENT_ID=your-public-client-id
KEYCLOAK_CLIENT_SECRET=your-client-secret

# Admin API Client (user management)
KEYCLOAK_ADMIN_CLIENT_ID=admin-cli
KEYCLOAK_ADMIN_CLIENT_SECRET=admin-client-secret

# Public key for JWT validation
KEYCLOAK_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nYOUR_PUBLIC_KEY_HERE\n-----END PUBLIC KEY-----"
```

### 5. Symfony Security Configuration

[](#5-symfony-security-configuration)

```
# config/packages/security.yaml
security:
    providers:
        keycloak_provider:
            id: keycloak.user_provider

    firewalls:
        # JWT Authentication for API
        api:
            pattern: ^/api
            stateless: true
            custom_authenticators: keycloak.jwt_authenticator
            provider: keycloak_provider
	    entry_point: keycloak.jwt_authenticator_entrypoint

        # OIDC Authentication for web interface
        main:
            pattern: ^/
            provider: keycloak_provider
            custom_authenticators: keycloak.authenticator
	    entry_point: keycloak.authenticator_entrypoint

    access_control:
        - { path: ^/auth, roles: PUBLIC_ACCESS }
        - { path: ^/api/public, roles: PUBLIC_ACCESS }
        - { path: ^/api, roles: ROLE_USER }
        - { path: ^/admin, roles: ROLE_ADMIN }
```

### 6. Routes Configuration

[](#6-routes-configuration)

```
# config/routes/keycloak.yaml
keycloak_bundle:
    resource: '@KeycloakBundle/config/routes.yaml'
    prefix: /auth
```

Core Services
-------------

[](#core-services)

### KeycloakAdminService

[](#keycloakadminservice)

Service for user management via Keycloak Admin API.

#### Main Methods

[](#main-methods)

```
use Zepekegno\KeycloakBundle\Service\KeycloakAdminService;

// Service injection
public function __construct(
    private KeycloakAdminService $keycloakAdminService
) {}

// User creation with custom attributes
$userId = $this->keycloakAdminService->createUser(
    data: [
        'username' => 'john.doe',
        'email' => 'john@example.com',
        'firstName' => 'John',
        'lastName' => 'Doe'
    ],
    realmRoles: ['user'],
    clientRoles: ['app-user'],
    password: 'SecurePassword123!',
    attributes: [
        'platform' => ['web'],
        'registration_source' => ['website']
    ],
    requiredActions: ['VERIFY_EMAIL']
);

// Send verification email
$this->keycloakAdminService->sendVerificationEmail($userId);

// Update user attributes
$this->keycloakAdminService->updateUserAttributes($userId, [
    'last_login_platform' => ['mobile'],
    'preferences' => ['theme:dark', 'lang:en']
]);

// Assign roles
$this->keycloakAdminService->assignRealmRoles($userId, ['premium_user']);
$this->keycloakAdminService->assignClientRoles($userId, 'my-app', ['advanced_features']);
```

### OIDCService

[](#oidcservice)

Service for OIDC/OAuth 2.0 authentication with PKCE support.

#### Main Methods

[](#main-methods-1)

```
use Zepekegno\KeycloakBundle\Service\OIDCService;

// Service injection
public function __construct(
    private OIDCService $oidcService
) {}

// Generate login URL with PKCE
$codeVerifier = $this->oidcService->generateCodeVerifier();
$state = bin2hex(random_bytes(16));

$loginUrl = $this->oidcService->getLoginUrl(
    codeVerifier: $codeVerifier,
    state: $state,
    additionalParams: [
        'scope' => 'openid email profile',
        'prompt' => 'login', // Force credential input
        'max_age' => 3600    // Max session duration
    ]
);

// Store in session for callback
$session->set('keycloak_code_verifier', $codeVerifier);
$session->set('keycloak_state', $state);

// Exchange authorization code for tokens
$tokens = $this->oidcService->exchangeCode(
    code: $request->get('code'),
    codeVerifier: $session->get('keycloak_code_verifier')
);

// Validate and decode JWT token
$tokenData = $this->oidcService->validateToken($tokens['access_token']);

// Extract Bearer token from request
$bearerToken = $this->oidcService->extractBearerToken($request);

// Global logout URL
$logoutUrl = $this->oidcService->getLogoutUrl(refreshToken: $tokens['refresh_token']);
```

### TokenRefreshService

[](#tokenrefreshservice)

Service dedicated to token refresh management.

#### Main Methods

[](#main-methods-2)

```
use Zepekegno\KeycloakBundle\Service\TokenRefreshService;

// Service injection
public function __construct(
    private TokenRefreshService $tokenRefreshService
) {}

// Check for token near expiration
if ($this->tokenRefreshService->isTokenNearExpiration($session, 300)) {
    // Token expires in less than 5 minutes
    $newTokens = $this->tokenRefreshService->refreshTokens(
        $session->get('keycloak_refresh_token')
    );

    // Update tokens in session
    $this->tokenRefreshService->updateSessionTokens($session, $newTokens);
}

// Automatic refresh with error handling
try {
    $refreshedTokens = $this->tokenRefreshService->refreshTokensWithRetry(
        refreshToken: $session->get('keycloak_refresh_token'),
        maxRetries: 3
    );
} catch (\Exception $e) {
    // Redirect to login page on failure
    return $this->redirectToRoute('keycloak_login');
}
```

---

Security System
---------------

[](#security-system)

### KeycloakUser

[](#keycloakuser)

Class representing a Keycloak user in the Symfony security system.

#### Properties and Methods

[](#properties-and-methods)

```
use Zepekegno\KeycloakBundle\Security\KeycloakUser;

// Creating a Keycloak user
$user = new KeycloakUser(
    id: 'keycloak-user-uuid',
    username: 'john.doe',
    email: 'john@example.com',
    roles: ['ROLE_USER', 'ROLE_PREMIUM'],
    attributes: [
        'sub' => 'keycloak-user-uuid',
        'preferred_username' => 'john.doe',
        'email' => 'john@example.com',
        'platform' => 'web',
        'realm_access' => ['roles' => ['user', 'premium']],
        'resource_access' => [
            'my-app' => ['roles' => ['app-user']]
        ]
    ]
);

// Data access
$userId = $user->getId();                    // Keycloak UUID
$email = $user->getEmail();                  // User email
$username = $user->getUsername();            // Username
$roles = $user->getRoles();                  // Symfony roles
$attributes = $user->getAttributes();        // All token attributes
$platform = $user->getAttribute('platform'); // Specific attribute
```

### KeycloakUserProvider

[](#keycloakuserprovider)

User provider to create `KeycloakUser` objects from tokens.

### Controllers and Routes

[](#controllers-and-routes)

### AuthController

[](#authcontroller)

Main controller for authentication management.

#### Available Routes

[](#available-routes)

RouteMethodDescription`/auth/login`GETRedirect to Keycloak`/auth/callback`GETOIDC Callback`/auth/profile`GETUser profile`/auth/logout`GET/POSTGlobal logout#### Controller Methods

[](#controller-methods)

```
use Zepekegno\KeycloakBundle\Controller\AuthController;

// Redirect to Keycloak login page
public function login(Request $request): RedirectResponse
{
    $codeVerifier = $this->oidcService->generateCodeVerifier();
    $state = bin2hex(random_bytes(16));

    $session = $request->getSession();
    $session->set('keycloak_code_verifier', $codeVerifier);
    $session->set('keycloak_state', $state);

    $loginUrl = $this->oidcService->getLoginUrl($codeVerifier, $state, [
        'scope' => 'openid email profile'
    ]);

    return new RedirectResponse($loginUrl);
}

// Handle OIDC callback
public function callback(Request $request): RedirectResponse
{
    // Automatically handled by KeycloakAuthenticator
    // Redirects according to configured roles
}

// Display user profile
public function profile(Security $security): JsonResponse
{
    /** @var KeycloakUser $user */
    $user = $security->getUser();

    return new JsonResponse([
        'id' => $user->getId(),
        'username' => $user->getUsername(),
        'email' => $user->getEmail(),
        'roles' => $user->getRoles(),
        'attributes' => $user->getAttributes()
    ]);
}

// Global logout
public function logout(Request $request): RedirectResponse
{
    $session = $request->getSession();
    $refreshToken = $session->get('keycloak_refresh_token');

    $logoutUrl = $this->oidcService->getLogoutUrl($refreshToken);

    $session->invalidate();

    return new RedirectResponse($logoutUrl);
}
```

Practical Usage
---------------

[](#practical-usage)

### User Registration

[](#user-registration)

```
// In a registration controller
#[Route('/register', methods: ['POST'])]
public function register(
    Request $request,
    KeycloakAdminService $keycloakAdmin
): JsonResponse {
    $data = json_decode($request->getContent(), true);

    try {
        $userId = $keycloakAdmin->createUser(
            data: [
                'username' => $data['username'],
                'email' => $data['email'],
                'firstName' => $data['firstName'],
                'lastName' => $data['lastName']
            ],
            realmRoles: ['user'],
            clientRoles: [],
            password: $data['password'],
            attributes: [
                'platform' => [$data['platform'] ?? 'web'],
                'registration_date' => [date('Y-m-d H:i:s')]
            ],
            requiredActions: ['VERIFY_EMAIL']
        );

        // Automatic verification email sending
        $keycloakAdmin->sendVerificationEmail($userId);

        return new JsonResponse([
            'success' => true,
            'message' => 'User created. Check your email.',
            'user_id' => $userId
        ]);

    } catch (\Exception $e) {
        return new JsonResponse([
            'success' => false,
            'message' => 'Creation error: ' . $e->getMessage()
        ], 400);
    }
}
```

### API Authentication with JWT

[](#api-authentication-with-jwt)

```
// Middleware to verify JWT tokens
#[Route('/api/data', methods: ['GET'])]
public function getData(Security $security): JsonResponse
{
    // User is automatically authenticated by JwtAuthenticator
    /** @var KeycloakUser $user */
    $user = $security->getUser();

    // Role verification
    if (!$security->isGranted('ROLE_USER')) {
        return new JsonResponse(['error' => 'Access denied'], 403);
    }

    // Access to custom attributes
    $platform = $user->getAttributes()['platform'] ?? 'unknown';

    return new JsonResponse([
        'data' => 'Sensitive data',
        'user' => $user->getEmail(),
        'platform' => $platform
    ]);
}
```

### Silent SSO

[](#silent-sso)

```
// SSO verification without user interaction
public function checkSso(OIDCService $oidc, Request $request): JsonResponse
{
    $codeVerifier = $oidc->generateCodeVerifier();
    $state = bin2hex(random_bytes(16));

    $ssoUrl = $oidc->getSsoLoginUrl($codeVerifier, $state);

    // Storage for callback
    $session = $request->getSession();
    $session->set('keycloak_code_verifier', $codeVerifier);
    $session->set('keycloak_state', $state);

    return new JsonResponse([
        'sso_url' => $ssoUrl,
        'method' => 'iframe' // For silent verification
    ]);
}
```

### Token Management with Refresh

[](#token-management-with-refresh)

```
// Service to keep tokens up to date
public function ensureValidToken(
    Request $request,
    TokenRefreshService $tokenRefresh
): ?array {
    $session = $request->getSession();

    // Check expiration
    if ($tokenRefresh->isTokenNearExpiration($session, 300)) {
        try {
            $refreshToken = $session->get('keycloak_refresh_token');
            $newTokens = $tokenRefresh->refreshTokens($refreshToken);

            // Update session
            $tokenRefresh->updateSessionTokens($session, $newTokens);

            return $newTokens;
        } catch (\Exception $e) {
            // Invalid refresh token
            $session->invalidate();
            return null;
        }
    }

    return [
        'access_token' => $session->get('keycloak_access_token'),
        'refresh_token' => $session->get('keycloak_refresh_token')
    ];
}
```

Advanced Configuration
----------------------

[](#advanced-configuration)

### Custom User Provider

[](#custom-user-provider)

```
// src/Security/CustomUserProvider.php
use Aetherius\KeycloakBundle\Security\KeycloakUser;
use Symfony\Component\Security\Core\User\UserProviderInterface;

class CustomUserProvider implements UserProviderInterface
{
    public function __construct(
        private UserRepository $userRepository
    ) {}

    public function loadUserByIdentifier(string $identifier): UserInterface
    {
        // Load local user from database
        $localUser = $this->userRepository->findByKeycloakId($identifier);

        if (!$localUser) {
            // Create local user if necessary
            $localUser = $this->createLocalUser($identifier);
        }

        // Return enriched user
        return new EnrichedKeycloakUser(
            $localUser,
            $identifier
        );
    }

    // ... other required methods
}
```

```
# Configuration to use custom provider
keycloak:
    user_provider_service: 'App\Security\CustomUserProvider'
```

### Event Management

[](#event-management)

```
// src/EventListener/AuthenticationListener.php
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\Event\LoginSuccessEvent;

class AuthenticationListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            LoginSuccessEvent::class => 'onLoginSuccess',
        ];
    }

    public function onLoginSuccess(LoginSuccessEvent $event): void
    {
        $user = $event->getUser();

        if ($user instanceof KeycloakUser) {
            // Custom logic after login
            $this->updateLastLogin($user);
            $this->logUserActivity($user);
        }
    }
}
```

### Multi-Environment Configuration

[](#multi-environment-configuration)

```
# config/packages/dev/keycloak.yaml
keycloak:
    verify_token: false  # Disable in development

# config/packages/prod/keycloak.yaml
keycloak:
    verify_token: true   # Enable in production
```

Integration Examples
--------------------

[](#integration-examples)

### Mobile Application with API

[](#mobile-application-with-api)

```
// API controller for mobile
#[Route('/api/mobile', name: 'api_mobile_')]
class MobileApiController extends AbstractController
{
    #[Route('/login', methods: ['POST'])]
    public function mobileLogin(
        Request $request,
        OIDCService $oidc
    ): JsonResponse {
        $data = json_decode($request->getContent(), true);

        // Generate login URL for mobile
        $codeVerifier = $oidc->generateCodeVerifier();
        $state = bin2hex(random_bytes(16));

        $loginUrl = $oidc->getLoginUrl($codeVerifier, $state, [
            'scope' => 'openid email profile offline_access',
            'prompt' => 'login'
        ]);

        return new JsonResponse([
            'login_url' => $loginUrl,
            'code_verifier' => $codeVerifier,
            'state' => $state
        ]);
    }

    #[Route('/token', methods: ['POST'])]
    public function exchangeToken(
        Request $request,
        OIDCService $oidc
    ): JsonResponse {
        $data = json_decode($request->getContent(), true);

        try {
            $tokens = $oidc->exchangeCode(
                $data['code'],
                $data['code_verifier']
            );

            return new JsonResponse([
                'access_token' => $tokens['access_token'],
                'refresh_token' => $tokens['refresh_token'],
                'expires_in' => $tokens['expires_in']
            ]);
        } catch (\Exception $e) {
            return new JsonResponse([
                'error' => 'invalid_grant',
                'error_description' => $e->getMessage()
            ], 400);
        }
    }
}
```

### Token Validation Middleware

[](#token-validation-middleware)

```
// src/EventListener/TokenValidationListener.php
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;

class TokenValidationListener
{
    public function __construct(
        private OIDCService $oidcService,
        private TokenRefreshService $tokenRefreshService
    ) {}

    public function onKernelRequest(RequestEvent $event): void
    {
        $request = $event->getRequest();

        // Check only API routes
        if (!str_starts_with($request->getPathInfo(), '/api/')) {
            return;
        }

        $token = $this->oidcService->extractBearerToken($request);
        if (!$token) {
            return; // Let authenticator handle
        }

        // Token validation
        $tokenData = $this->oidcService->validateToken($token);
        if (!$tokenData) {
            throw new UnauthorizedHttpException('Bearer', 'Invalid token');
        }

        // Expiration check
        if (isset($tokenData['exp']) && $tokenData['exp'] < time()) {
            throw new UnauthorizedHttpException('Bearer', 'Token expired');
        }

        // Store token data for later use
        $request->attributes->set('token_data', $tokenData);
    }
}
```

Troubleshooting
---------------

[](#troubleshooting)

### Common Issues

[](#common-issues)

#### 1. Token Validation Error

[](#1-token-validation-error)

**Symptom**: `Invalid JWT token`

**Solutions**:

- Check public key in `KEYCLOAK_PUBLIC_KEY`
- Ensure realm is correct
- Verify `verify_token` is configured correctly

```
# Retrieve realm public key
curl "$KEYCLOAK_BASE_URL/realms/$KEYCLOAK_REALM/protocol/openid-connect/certs"
```

#### 2. PKCE Error

[](#2-pkce-error)

**Symptom**: `Code verifier missing from session`

**Solutions**:

- Check Symfony session configuration
- Ensure cookies are enabled
- Verify HTTPS configuration in production

#### 3. Redirection Issues

[](#3-redirection-issues)

**Symptom**: Redirection loops

**Solutions**:

- Check `redirect_routes` in configuration
- Ensure routes exist
- Verify user roles

#### 4. Admin API Errors

[](#4-admin-api-errors)

**Symptom**: `Unauthorized` during user creation

**Solutions**:

- Check admin client credentials
- Ensure client has necessary permissions
- Verify admin client roles in Keycloak

### Debug Commands

[](#debug-commands)

```
# Check bundle configuration
php bin/console debug:config keycloak

# List bundle services
php bin/console debug:container | grep keycloak

# Check routes
php bin/console debug:router | grep keycloak

# Test Keycloak connectivity
curl "$KEYCLOAK_BASE_URL/realms/$KEYCLOAK_REALM/.well-known/openid_configuration"
```

### Useful Logs

[](#useful-logs)

```
# config/packages/dev/monolog.yaml
monolog:
    handlers:
        keycloak:
            type: stream
            path: "%kernel.logs_dir%/keycloak.log"
            level: debug
            channels: ["keycloak"]
```

```
// Usage in services
use Psr\Log\LoggerInterface;

public function __construct(
    private LoggerInterface $logger
) {}

public function someMethod(): void
{
    $this->logger->info('Keycloak operation', [
        'operation' => 'user_creation',
        'user_id' => $userId
    ]);
}
```

Complete API Reference
----------------------

[](#complete-api-reference)

### KeycloakAdminService

[](#keycloakadminservice-1)

MethodParametersReturnDescription`createUser()`data, realmRoles, clientRoles, password,
 attributes, requiredActionsstringCreates a new user in keycloak`sendVerificationEmail()`userIdvoidSends a verification email to the user`updateUserAttributes()`userId, attributesvoidUpdates attributes`assignRolesToUser()`userId, rolesvoidAssigns realm roles to the user`assignCleintRolesToUser()`userId, rolesvoidAssigns client roles to the user`findUserByEmail()`userIdarraySearches for users by email`updateUserAttributes()`userId, attributesvoidUpdate user attributes`getUser()`userIdarrayretreives user information`getAdminToken()`-stringGets an access token for the admin API### OIDCService

[](#oidcservice-1)

MethodParametersReturnDescription`generateCodeVerifier()`lengthstringGenerates PKCE code verifier`getLoginUrl()`codeVerifier, state, additionalParamsstringLogin URL`getSsoLoginUrl()`codeVerifier, statestringSilent SSO URL`exchangeCode()`code, codeVerifierarrayExchange code → tokens`validateToken()`tokenarray|nullValidates and decodes JWT`extractBearerToken()`requeststring|nullExtracts Bearer token`getLogoutUrl()`idToken, redirectUristringLogout URL### TokenRefreshService

[](#tokenrefreshservice-1)

MethodParametersReturnDescription`isTokenNearExpiration()`session, marginSecondsboolChecks near expiration`isTokenExpired()`sessionboolChecks expiration`refreshTokens()`refreshTokenarrayRefreshes tokens`updateSessionTokens()`session, tokensvoidUpdates session`refreshTokensWithRetry()`refreshToken, maxRetriesarrayRefreshes with retry### License

[](#license)

This bundle is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

### Contributing

[](#contributing)

1. Fork the project
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

### Development Setup

[](#development-setup)

```
# Clone the repository
git clone https://github.com/zepekegno224/keycloakBundle.git
cd keycloakBundle

# Install dependencies
composer install

# Run tests
php bin/phpunit

# Check code style
php bin/php-cs-fixer fix --dry-run
```

### Support

[](#support)

For questions or issues:

- Email:
- Issues: [GitHub Issues](https://github.com/zepekegno224/keycloakBundle/issues)
- Documentation: [Wiki](https://github.com/zepekegno224/keycloakBundle/wiki)
- Discussions: [GitHub Discussions](https://github.com/zepekegno224/keycloakBundle/discussions)

Full Setup Guide
----------------

[](#full-setup-guide)

For a step-by-step integration with Symfony (installation, configuration, security, routes, examples), see docs/SETUP.md.

Wiki
----

[](#wiki)

For detailed usage guides, security setup (Web and API), services documentation, and troubleshooting, see docs/wiki/Home.md.

###  Health Score

29

—

LowBetter than 60% of packages

Maintenance59

Moderate activity, may be stable

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

2

Last Release

261d ago

Major Versions

v0.1.0 → v1.0.02025-08-22

### Community

Maintainers

![](https://www.gravatar.com/avatar/9a502394a6431a335e290b6f39ac90b09b44a46df5cd95ac3591e6bc09130b7b?d=identicon)[zepekegno224](/maintainers/zepekegno224)

---

Top Contributors

[![zepekegno224](https://avatars.githubusercontent.com/u/59239718?v=4)](https://github.com/zepekegno224 "zepekegno224 (1 commits)")

---

Tags

AuthenticationSSOSymfony BundleOpenID Connectkeycloakoidc

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/zepekegno-keycloak-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/zepekegno-keycloak-bundle/health.svg)](https://phpackages.com/packages/zepekegno-keycloak-bundle)
```

###  Alternatives

[web-auth/webauthn-framework

FIDO2/Webauthn library for PHP and Symfony Bundle.

50570.7k1](/packages/web-auth-webauthn-framework)[scheb/2fa

Two-factor authentication for Symfony applications (please use scheb/2fa-bundle to install)

578630.7k1](/packages/scheb-2fa)[web-auth/webauthn-symfony-bundle

FIDO2/Webauthn Security Bundle For Symfony

63397.4k6](/packages/web-auth-webauthn-symfony-bundle)[scheb/2fa-bundle

A generic interface to implement two-factor authentication in Symfony applications

6914.0M62](/packages/scheb-2fa-bundle)[auth0/symfony

Symfony SDK for Auth0 Authentication and Management APIs.

128738.1k](/packages/auth0-symfony)[facile-it/php-openid-client

OpenID (OIDC) Client

42592.7k7](/packages/facile-it-php-openid-client)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
