Installation Add the bundle to your Laravel project via Composer:
composer require dbp/relay-keycloak-bundle
Register the bundle in config/app.php under providers:
DBP\Relay\KeycloakBundle\KeycloakServiceProvider::class,
Configuration Publish the default config file:
php artisan vendor:publish --provider="DBP\Relay\KeycloakBundle\KeycloakServiceProvider" --tag="config"
Update .env with Keycloak server details:
KEYCLOAK_REALM=your-realm
KEYCLOAK_CLIENT_ID=your-client-id
KEYCLOAK_CLIENT_SECRET=your-client-secret
KEYCLOAK_BASE_URL=https://your-keycloak-server/auth
First Use Case: Authentication Use the facade to authenticate a user:
use DBP\Relay\KeycloakBundle\Facades\Keycloak;
$token = Keycloak::authenticate([
'username' => '[email protected]',
'password' => 'password123',
'grant_type' => 'password'
]);
User Management
$user = Keycloak::createUser([
'username' => 'newuser',
'email' => '[email protected]',
'enabled' => true,
'credentials' => [
['type' => 'password', 'value' => 'securepass', 'temporary' => false]
]
]);
Keycloak::updateUser($userId, ['email' => '[email protected]']);
Token Handling
$refreshedToken = Keycloak::refreshToken($refreshToken);
$isValid = Keycloak::introspectToken($token);
Role Management
Keycloak::assignRole($userId, 'admin');
$roles = Keycloak::getUserRoles($userId);
Middleware for Protected Routes Create middleware to validate Keycloak tokens:
namespace App\Http\Middleware;
use Closure;
use DBP\Relay\KeycloakBundle\Facades\Keycloak;
class ValidateKeycloakToken
{
public function handle($request, Closure $next)
{
$token = $request->bearerToken();
if (!$token || !Keycloak::introspectToken($token)) {
abort(401, 'Unauthorized');
}
return $next($request);
}
}
Register in app/Http/Kernel.php:
protected $routeMiddleware = [
'keycloak.auth' => \App\Http\Middleware\ValidateKeycloakToken::class,
];
Laravel Auth Integration
Extend Laravel’s Authenticatable to use Keycloak tokens:
use DBP\Relay\KeycloakBundle\Facades\Keycloak;
class KeycloakUserProvider implements Authenticatable
{
public function retrieveByToken($token)
{
$user = Keycloak::introspectToken($token);
return $user ? new User($user) : null;
}
}
Token Expiry Handling
401 Unauthorized responses gracefully and refresh tokens when needed.Role Mapping
'role_mappings' => [
'admin' => 'Keycloak-Admin-Role',
'user' => 'Keycloak-User-Role',
],
Error Handling
400 Bad Request for invalid credentials). Wrap API calls in try-catch blocks:
try {
$token = Keycloak::authenticate($credentials);
} catch (\DBP\Relay\KeycloakBundle\Exceptions\KeycloakException $e) {
Log::error('Keycloak auth failed: ' . $e->getMessage());
abort(401);
}
Rate Limiting
use DBP\Relay\KeycloakBundle\KeycloakManager;
$manager = app(KeycloakManager::class);
$manager->setRetryPolicy(new \GuzzleHttp\RetryMiddleware([
'max_retries' => 3,
'delay' => 100,
'multiplier' => 2,
]));
Enable API Logging
Configure Guzzle HTTP client logging in config/keycloak.php:
'http_client' => [
'debug' => env('KEYCLOAK_DEBUG', false),
],
Check logs in storage/logs/laravel.log for API request/response details.
Test with Postman
Use Postman to manually test Keycloak endpoints (e.g., /auth/realms/{realm}/protocol/openid-connect/token) before integrating into Laravel.
Validate Config
Ensure .env values match your Keycloak server:
KEYCLOAK_BASE_URL must include /auth (e.g., https://keycloak.example.com/auth).KEYCLOAK_REALM must exist in Keycloak.Custom Claims
Extend the User model to include Keycloak claims:
class User extends Authenticatable
{
public function getKeycloakClaims()
{
return Keycloak::getUserInfo($this->keycloak_id)['userinfo'];
}
}
Webhook Events Listen to Keycloak events (e.g., user creation) via Keycloak’s admin REST API:
Keycloak::listenForEvent('create', function ($user) {
// Trigger Laravel event or queue job
event(new UserRegistered($user));
});
Custom Adapters Override the default HTTP adapter for custom logic (e.g., proxy support):
$manager = app(KeycloakManager::class);
$manager->setHttpClient(new \GuzzleHttp\Client([
'base_uri' => env('KEYCLOAK_BASE_URL'),
'proxy' => env('HTTP_PROXY'),
]));
How can I help you explore Laravel packages today?