Installation:
composer require benji07/sso-bundle
Ensure your composer.json includes the package under require.
Enable the Bundle:
Add to config/bundles.php:
Benji07\SsoBundle\Benji07SsoBundle::class => ['all' => true],
Routing:
Import the bundle’s routing in config/routes.yaml:
Benji07SsoBundle:
resource: "@Benji07SsoBundle/Resources/config/routing.yml"
Basic Security Configuration:
Update config/packages/security.yaml:
firewalls:
main:
sso:
check_path: /sso/login_check
First Use Case:
Configure a single SSO provider (e.g., Steam) in config/packages/benji07_sso.yaml:
benji07_sso:
user_manager: app.user_manager
providers:
steam:
service: benji07.sso.provider.steam
options:
apiKey: "%env(STEAM_API_KEY)%"
Create a User Manager:
Implement UserManagerInterface and register it as a service in config/services.yaml:
services:
App\UserManager:
class: App\Service\UserManager
arguments: ["@doctrine.orm.entity_manager"]
Test the Flow:
Access /sso/login/steam to trigger the SSO login. Verify the user is redirected and authenticated.
Provider Integration:
AbstractProvider for custom providers (e.g., Discord, GitHub).getAuthUrl() and getUserInfo() methods to handle provider-specific logic.// src/Service/DiscordProvider.php
class DiscordProvider extends AbstractProvider {
public function getAuthUrl() {
return "https://discord.com/api/oauth2/authorize?...";
}
}
User Management:
findUser() to locate existing users by provider data (e.g., Steam ID).createUser() to handle new registrations or redirect to a registration form.// src/Service/UserManager.php
public function findUser($providerName, $userInfo) {
return $this->em->getRepository(User::class)
->findOneBy(['steamId' => $userInfo['steamid']]);
}
Session Handling:
$request->getSession()->get('sso_user') to access provider data after authentication.$request->getSession()->remove('sso_user');
Post-Authentication Logic:
SSOAuthenticationSuccessEvent) to trigger actions after login.// src/EventListener/SSOListener.php
public function onSSOAuthSuccess(SSOAuthenticationSuccessEvent $event) {
$user = $event->getUser();
// Log user activity, update last login, etc.
}
Register in config/services.yaml:
services:
App\EventListener\SSOListener:
tags:
- { name: kernel.event_listener, event: sso.authentication.success, method: onSSOAuthSuccess }
Multi-Provider Setup:
benji07_sso.providers and expose them in the UI via links:
{% for providerName, _ in app.container.get('benji07_sso.provider.manager').getProviders() %}
<a href="{{ path('sso_login', {'provider': providerName}) }}">{{ providerName|capitalize }}</a>
{% endfor %}
symfony/flex to auto-configure the bundle if available..env (e.g., STEAM_API_KEY=your_key).steamId to your User entity).// src/Twig/SSOExtension.php
public function isSSOAuthenticated(Request $request) {
return $request->getSession()->has('_security_main');
}
Provider Service Naming:
benji07_sso.providers matches the registered service name (e.g., benji07.sso.provider.steam).bin/console debug:container benji07.sso.provider.Session Expiry:
Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage for debugging session data.User Manager Not Found:
user_manager is misconfigured, the bundle throws a RuntimeException.benji07_sso.user_manager matches your registered service.CSRF Protection:
/sso/login_check endpoint is vulnerable to CSRF if not properly secured.firewalls:
main:
sso:
check_path: /sso/login_check
csrf_protection: true
Provider-Specific Quirks:
getAuthUrl() parameters.Enable Debug Mode:
Set APP_ENV=dev in .env to see detailed errors and logs.
Log Provider Responses:
Add logging in your provider’s getUserInfo() method:
$this->logger->debug('Provider response:', ['data' => $response]);
Check Events:
Use the debug:event-dispatcher command to verify if events are fired:
bin/console debug:event-dispatcher
Session Dump: Dump session data after SSO login to verify provider data:
dump($request->getSession()->all());
Custom Providers:
AbstractProvider and register the service with the benji07.sso.provider.{name} tag.services:
benji07.sso.provider.discord:
class: App\Service\DiscordProvider
tags: ['benji07.sso.provider']
Custom User Entities:
User entity to include provider-specific fields (e.g., steamId, discordId).// src/Entity/User.php
/**
* @ORM\Column(type="string", nullable=true)
*/
private $steamId;
Post-Authentication Redirects:
SSOAuthenticationSuccessHandler to customize redirects:
// src/EventListener/CustomSSOHandler.php
public function onSSOAuthSuccess(SSOAuthenticationSuccessEvent $event) {
$event->setRedirectUrl('/dashboard');
}
Register as a listener (as shown in Implementation Patterns).Two-Factor Authentication (2FA):
UserManager:
public function createUser($providerName, $userInfo) {
$user = new User();
// ... set user data ...
if (!$user->hasTwoFactorEnabled()) {
return $this->redirectTo2FA($user);
}
return $user;
}
Provider-Specific Templates:
sso/login.html.twig) in templates/Benji07SsoBundle/ to customize the login UI.How can I help you explore Laravel packages today?