Install via Composer
composer require ahs/persona-bundle
Enable the Bundle
Add to app/AppKernel.php:
new AHS\PersonaBundle\AHSPersonaBundle(),
Configure Security
Update app/config/security.yml:
firewalls:
persona_secured:
pattern: ^/
persona: true
logout: true
anonymous: true
Set Persona URLs
Configure in app/config/config.yml:
ahs_persona:
verifier_url: "https://verifier.login.persona.org/verify"
audience_url: "https://your-app.example.com"
First Use Case
Deploy and visit your app. The bundle provides a /login route (default) for Persona authentication. Test by clicking the login link—it redirects to Mozilla Persona for verification.
Authentication Flow
/login).verifier_url).assertion query param.Customizing the Login Route
Override the default route in routing.yml:
ahs_persona_login:
path: /auth/persona
defaults: { _controller: AHSPersonaBundle:Security:login }
User Identity Handling
The bundle uses the email from the Persona assertion as the Symfony username. Extend the AHSPersonaUserProvider to map emails to custom user entities:
// src/AHS/PersonaBundle/DependencyInjection/Compiler/UserProviderPass.php
class UserProviderPass extends CompilerPass {
public function process(ContainerBuilder $container) {
$definition = $container->findDefinition('ahs_persona.user_provider');
$definition->setClass('AppBundle\Security\CustomPersonaUserProvider');
}
}
Twig Integration (Manual) Since the bundle lacks built-in Twig helpers, create a custom extension:
{% if app.user %}
Logged in as {{ app.user.email }}
<a href="{{ path('logout') }}">Logout</a>
{% else %}
<a href="{{ path('ahs_persona_login') }}">Login with Persona</a>
{% endif %}
FOSUserBundle Compatibility (Partial)
While the bundle doesn’t natively support FOSUserBundle, manually register a UserProvider:
# app/config/security.yml
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
login_path: ahs_persona_login
check_path: ahs_persona_check
Deprecated Symfony Version The bundle requires Symfony 2.1–2.3-dev. Use with Symfony 2.7/2.8 may break due to API changes. Test thoroughly or fork the bundle.
In-Memory Provider Limitation
The default InMemoryUserProvider stores users in memory. For production, implement a custom provider (e.g., Doctrine-based) to persist sessions:
// src/AppBundle/Security/CustomPersonaUserProvider.php
class CustomPersonaUserProvider extends AHSPersonaUserProvider {
public function loadUserByUsername($email) {
return $this->entityManager->getRepository('AppBundle:User')
->findOneBy(['email' => $email]);
}
}
CSRF Token Issues
The /login route may fail if CSRF protection is enabled. Disable it for the Persona firewall:
firewalls:
persona_secured:
pattern: ^/
persona: true
logout: true
anonymous: true
context: main # Ensure this matches your security context
Audience URL Mismatch
The audience_url must match the exact domain where users are redirected after login. Use HTTPS and avoid local dev URLs (e.g., http://localhost).
No Built-in Logout Button
The bundle provides a logout route (/logout) but no Twig helper. Create a custom route or use:
<a href="{{ path('logout', {'_route_params': {'_locale': app.request.locale}}) }}">Logout</a>
Enable Debugging
Add to config.yml to log assertions:
ahs_persona:
debug: true
Verify Assertions Manually
Check the assertion query param in the redirect URL. Use Mozilla’s Persona Verifier to validate it offline.
Check Browser Console Persona errors (e.g., invalid assertions) may appear in the browser console. Inspect the redirect flow:
your-app.com → persona.org → your-app.com?assertion=...
Clear Cache After Config Changes Run:
php app/console cache:clear
Custom User Provider
Override the AHSPersonaUserProvider to integrate with your user model:
// src/AppBundle/Security/CustomPersonaUserProvider.php
class CustomPersonaUserProvider extends AHSPersonaUserProvider {
public function loadUserByUsername($email) {
// Fetch user from DB or create if missing
}
}
Register it in services.yml:
services:
app.persona.user_provider:
class: AppBundle\Security\CustomPersonaUserProvider
arguments: [@doctrine.orm.entity_manager]
tags:
- { name: security.user_provider, id: persona }
Post-Login Redirects
Extend the AHSPersonaListener to redirect users after login:
// src/AppBundle/EventListener/PersonaLoginListener.php
class PersonaLoginListener {
public function onPersonaSuccess(GetResponseUserEvent $event) {
$request = $event->getRequest();
$session = $request->getSession();
$targetPath = $session->get('_security.main.target_path');
if (!$targetPath) {
$event->setResponse(new RedirectResponse('/dashboard'));
}
}
}
Register the listener in services.yml:
services:
app.persona.login_listener:
class: AppBundle\EventListener\PersonaLoginListener
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onPersonaSuccess }
Add Persona to Existing Firewall Combine with form/login firewalls:
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
persona:
verifier_url: "https://verifier.login.persona.org/verify"
audience_url: "https://your-app.example.com"
How can I help you explore Laravel packages today?