grizzlylab/ccdn-user-security-bundle
A Symfony bundle that adds user security features such as registration, authentication, password management, and account handling to CCDN-based applications. Provides reusable security components for integrating user accounts into Symfony projects.
Framework check before anything else. This is a Symfony bundle, not a Laravel package. It wires into Symfony's Kernel, DI container, symfony/security-*, and Twig — there is no service provider, no facade, no config file Laravel will read. A Laravel developer's realistic relationship with it is one of three:
Minimal steps if you actually are in that Symfony 5 app:
composer require grizzlylab/ccdn-user-security-bundle
Then, in order:
config/bundles.php — register Grizzlylab\CCDNUserSecurityBundle\CCDNUserSecurityBundle (confirm the exact FQCN in the repo's composer.json autoload.psr-4; forks frequently rename the namespace).config/routes/ccdn_user_security.yaml — import the bundle's routing resource from Resources/config/routing/.config/packages/ccdn_user_security.yaml — the config tree is the real API surface. Read DependencyInjection/Configuration.php first; that file tells you more than the README will.config/packages/security.yaml — point form_login.login_path / check_path at the bundle's login route.Where to look first, in this order: DependencyInjection/Configuration.php (what's configurable), Resources/config/routing* (what URLs you get), Controller/ (the actual behaviour), Resources/views/ (what you'll be overriding). The bundle is a thin orchestration layer — the User entity, registration, and profile almost certainly live in its sibling ccdn-user-user-bundle, which you will also need.
First use case: replace hand-rolled login + "forgot password" + "confirm your email" controllers in a legacy Symfony 5 app with the bundle's routes, then immediately override the templates to match your design system.
Laravel equivalent, if you're porting: laravel/fortify + Laravel\Fortify actions (AttemptToAuthenticate, SendPasswordResetLink, ResetUserPassword), MustVerifyEmail on the User model, and URL::temporarySignedRoute for confirmation links. Nearly everything this bundle does is a Fortify feature with a supported maintenance story.
Firewall wiring. The bundle supplies controllers and templates; Symfony's security component does the authentication. Typical shape:
# config/packages/security.yaml
security:
firewalls:
main:
anonymous: lazy
provider: app_user_provider
form_login:
login_path: ccdn_user_security_login
check_path: ccdn_user_security_login
logout:
path: ccdn_user_security_logout
Use route names rather than URLs — the bundle's route names are the only stable contract you get from a fork.
Template overriding. Symfony still honours templates/bundles/CCDNUserSecurityBundle/... for view overrides. Copy the bundle's Twig files there and restyle. Do this on day one — the shipped templates are Bootstrap-3-era and will not match anything modern.
Controller overriding. Bundle inheritance for controllers is gone in Symfony 4/5. Your options, in order of preference:
src/Controller/ and stop importing the bundle's route for that path.Email flows. Confirmation and password-reset mail is configured through the config tree (sender address, template names). Verify whether the fork still depends on swiftmailer/swiftmailer — Swiftmailer was abandoned in favour of symfony/mailer at the end of 2021, and a Symfony 5 fork that wasn't updated will break the moment you remove the Swiftmailer bridge. If it does, override the mailer service with a decorator that uses Symfony\Component\Mailer\MailerInterface.
Events as extension points. Hook Symfony\Component\Security\Http\Event\LoginSuccessEvent (or the older InteractiveLoginEvent on Symfony < 5.4) for last-login timestamps, audit logging, and post-reset session invalidation. This is the cleanest seam the bundle gives you — it doesn't need to know about it.
Porting to Laravel. Map the flows directly:
| Bundle concern | Laravel/Fortify equivalent |
|---|---|
| Login form + CSRF | Fortify POST /login, @csrf |
| Forgot password | Password::sendResetLink() |
| Reset password | ResetUserPassword action + password.reset broker |
| Email confirmation | MustVerifyEmail + verified middleware |
| Change password | PasswordController@update with current_password rule |
| Account lockout / throttling | RateLimiter::for('login') |
Reproduce the behaviour you need from the bundle's controllers line by line; do not try to bridge the two frameworks.
Treat the parent project as dead. CCDN's bundle family tracked Symfony 2.x. This fork claims Symfony 5. Check the branch and composer.json constraints before believing it: if the constraint is ^5.0 and the last commit predates Symfony 5.3, you have a problem, because 5.3 deprecated and 6.0 removed the custom authentication provider interfaces. If the bundle ships a UserProviderInterface/AuthenticationProviderInterface implementation, form login will still work but anything custom will emit deprecations now and fatal later. Verify with bin/console debug:container --deprecations after wiring it up.
getUsername() vs getUserIdentifier(). Symfony 5.3 renamed the contract. A fork that still calls getUsername() will log deprecations on every request; a User entity implementing both is the safe bridge.
The config split is confusing. Settings you expect here (registration roles, password strength, profile fields) frequently live in ccdn-user-user-bundle. When a config key "doesn't exist," run bin/console debug:config ccdn_user_security and debug:config ccdn_user_user before assuming the docs are wrong — they usually are, but the tree is authoritative.
Debugging checklist:
bin/console debug:router | grep -i ccdn — confirm the routes imported at all.bin/console debug:config ccdn_user_security — confirm your YAML keys were accepted (unknown keys are silently ignored in some older trees).bin/console lint:twig templates/bundles/CCDNUserSecurityBundle — catch overrides that reference removed blocks.security.access_control order and that check_path matches the route name, not a hardcoded path.Pin the version and vendor the fork. With 0 stars and 0 dependents, there is no upgrade path and no one to file issues against. Commit an exact version in composer.lock, and if you must ship it, fork to your own VCS, add CI, and treat yourself as the maintainer. Budget for replacing it.
Don't put it in production auth as-is. Abandoned authentication code is a standing security liability — password reset token generation, timing, and single-use semantics need review before you trust them. Compare against Fortify's PasswordBroker defaults and Symfony's own symfonycasts/reset-password-bundle, which is maintained and is the obvious migration target if you stay on Symfony.
Opportunity read. The high "opportunity" score here isn't a hidden-gem signal — it's the absence of a maintained option. The value in this repository is as a reference implementation of a complete auth flow, not as a dependency. Read it, port the ideas, leave the code behind.
How can I help you explore Laravel packages today?