daanvanberkel/openid-connect-bundle
Installation:
composer require daanvanberkel/openid-connect-bundle
Add to config/bundles.php:
Daanvanberkel\OpenidConnectBundle\DaanvanberkelOpenidConnectBundle::class => ['all' => true],
Configuration: Publish the default config:
php bin/console daanvanberkel:openid-connect:install
Edit config/packages/daanvanberkel_openid_connect.yaml with your provider details (e.g., Auth0, Okta, or custom OIDC endpoint).
First Use Case: Secure a route with OIDC authentication:
# config/routes.yaml
secured_route:
path: /dashboard
controller: App\Controller\DashboardController::index
methods: GET
requirements:
role: ROLE_USER
The bundle automatically handles redirects to the OIDC provider and token validation.
Authentication Flow:
authenticate route (default: /login/openid-connect) for user login.UserProvider interface).User Provider Integration:
Implement Daanvanberkel\OpenidConnectBundle\Security\User\UserProviderInterface to map OIDC claims to your user entity:
class CustomUserProvider implements UserProviderInterface
{
public function loadUserById(string $id): UserInterface
{
// Fetch user from DB or create if needed.
}
public function loadUserFromOidc(array $claims): UserInterface
{
// Map claims (e.g., `sub`, `email`) to your user entity.
}
}
Register it in config:
daanvanberkel_openid_connect:
user_provider: App\Security\User\CustomUserProvider
Role Assignment: Dynamically assign roles based on OIDC claims:
daanvanberkel_openid_connect:
role_claim: "https://example.com/roles" # Custom claim for roles
Logout: Extend the default logout to clear OIDC sessions:
// src/EventListener/OpenidConnectLogoutListener.php
use Daanvanberkel\OpenidConnectBundle\Event\OpenidConnectLogoutEvent;
class OpenidConnectLogoutListener
{
public function onLogout(OpenidConnectLogoutEvent $event)
{
// Revoke tokens or clean up state.
}
}
Register in services.yaml:
services:
App\EventListener\OpenidConnectLogoutListener:
tags:
- { name: kernel.event_listener, event: openid_connect.logout }
ROLE_USER or custom roles in firewalls:
security:
firewalls:
main:
oidc: true
logout:
path: /logout
target: /login
ClaimMapper to transform provider claims:
class CustomClaimMapper extends ClaimMapper
{
public function map(array $claims): array
{
$claims['custom_field'] = $claims['raw']['custom_claim'] ?? null;
return parent::map($claims);
}
}
Configure in services.yaml:
daanvanberkel_openid_connect.claim_mapper: '@App\Security\CustomClaimMapper'
Token Validation:
InvalidIdToken exceptions.php bin/console debug:config daanvanberkel_openid_connect
State Management:
CsrfTokenManager for state. If you customize the login route, ensure the state parameter is preserved in redirects.User Association:
loadUserFromOidc returns null, the user is not linked. Verify the user_provider is correctly implemented and the claims match your user model.CORS Issues:
EventListener or middleware, as the bundle doesn’t handle CORS by default.Enable Verbose Logging:
daanvanberkel_openid_connect:
debug: true
Logs appear in var/log/dev.log.
Token Inspection: Dump the decoded ID token in a controller:
use Daanvanberkel\OpenidConnectBundle\Security\OpenidConnectAuthenticator;
public function debugToken(OpenidConnectAuthenticator $authenticator)
{
$token = $authenticator->getUser()->getOidcToken();
var_dump($token->getClaims());
}
Custom Authenticators:
Extend OpenidConnectAuthenticator to add pre/post-auth logic:
class CustomAuthenticator extends OpenidConnectAuthenticator
{
protected function getOidcUser(array $claims, Token $token)
{
// Custom user logic.
}
}
Register in security.yaml:
security:
firewalls:
main:
oidc:
authenticator: App\Security\CustomAuthenticator
Provider-Specific Logic:
Use the OpenidConnectProviderEvent to modify provider configurations dynamically:
class DynamicProviderConfigListener
{
public function onProviderConfig(OpenidConnectProviderEvent $event)
{
if ($event->getProviderName() === 'auth0') {
$event->setConfig(['custom' => 'value']);
}
}
}
Tag the service:
services:
App\EventListener\DynamicProviderConfigListener:
tags:
- { name: kernel.event_listener, event: openid_connect.provider_config }
Nonce Handling:
For PKCE flows, customize the NonceManager to store/validate nonces in your preferred storage (e.g., Redis):
class RedisNonceManager implements NonceManagerInterface
{
public function generateNonce(): string
{
return bin2hex(random_bytes(32));
}
public function isValid(string $nonce): bool
{
// Check Redis.
}
}
Bind it in services.yaml:
daanvanberkel_openid_connect.nonce_manager: '@App\Security\RedisNonceManager'
openid email profile by default. Override in config:
daanvanberkel_openid_connect:
scopes: ["openid", "email", "custom_scope"]
daanvanberkel_openid_connect:
jwks_refresh_interval: 3600 # 1 hour
How can I help you explore Laravel packages today?