symfony/security-bundle
Symfony SecurityBundle integrates the Security component into the Symfony full-stack framework, providing authentication, authorization, firewalls, user providers, and access control. Part of the main Symfony repository with established contribution and issue workflows.
Installation:
composer require symfony/security-bundle
Add to config/bundles.php:
return [
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
];
Basic Configuration (config/packages/security.yaml):
security:
enable_authenticator_manager: true
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
firewalls:
main:
lazy: true
provider: app_user_provider
form_login: ~
logout: ~
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
First Use Case:
User entity with UserInterface and PasswordAuthenticatedUserInterface.use Symfony\Component\Security\Http\Attribute\IsGranted;
#[IsGranted('ROLE_USER')]
public function secureAction(): Response { ... }
Form Login:
firewalls:
main:
form_login:
login_path: app_login
check_path: app_login_check
enable_csrf: true
AbstractAuthenticator for custom logic:
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
class CustomAuthenticator extends AbstractAuthenticator { ... }
OAuth/OIDC:
firewalls:
main:
oauth:
resource_owners:
github: { client_id: ..., client_secret: ..., scope: "user:email" }
security:oidc-token:generate CLI command for testing.Remember-Me:
firewalls:
main:
remember_me:
secret: '%kernel.secret%'
lifetime: 86400
path: /
Role-Based Access:
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
#[IsGranted] in controllers or access_decision() in Twig:
{% if is_granted('ROLE_ADMIN') %} ... {% endif %}
Voter Integration:
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
class CustomVoter implements VoterInterface { ... }
security.yaml:
security:
access_decision_manager:
strategy: unanimous
voters:
- App\Security\CustomVoter
Dynamic Roles:
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
$token = $this->tokenStorage->getToken();
$roles = $token->getRoleNames();
API Tokens:
firewalls:
api:
pattern: ^/api
stateless: true
jwt: ~
lexik/jwt-authentication-bundle for JWT.Rate Limiting:
security:
firewalls:
main:
login_throttling:
max_attempts: 5
interval: 3600
CSRF Protection:
firewalls:
main:
csrf_protection: ~
Profiler:
_profiler/security).Lazy Firewalls:
remember_me on POST requests to public routes (fixed in v8.0.6+).bin/console debug:security
Token Storage:
$this->container->get('security.token_storage')->setToken(null);
Deprecations:
hide_user_not_found (v7.4+).#[IsGranted] instead of callable voters (deprecated in v8.0+).OIDC/OAuth:
security:oidc-token:generate for testing:
bin/console security:oidc-token:generate --endpoint="https://your-provider.com/.well-known/openid-configuration"
Role Hierarchy:
bin/console debug:security role-hierarchy
bin/console debug:security role-hierarchy --format=mermaid
Custom Authenticators:
AuthenticatorInterface for reusable logic.AbstractAuthenticator for form-based auth.Event Listeners:
SecurityEvents:
use Symfony\Component\Security\Http\Event\AuthenticatorFailureEvent;
$dispatcher->addListener(SecurityEvents::AUTHENTICATION_FAILURE, function (AuthenticatorFailureEvent $event) { ... });
User Providers:
UserProviderInterface for custom user loading:
class CustomUserProvider implements UserProviderInterface { ... }
security.yaml:
providers:
custom:
id: App\Security\CustomUserProvider
Caching:
security:
access_decision_manager:
cache: app.cache.security
Lazy Loading:
lazy: true in firewalls to defer authentication until first request.Token Storage:
getToken() calls; store in a variable if reused.CSRF Tokens:
enable_csrf: true for form logins to prevent CSRF attacks.Session Fixation:
security:
session_fixation_strategy: new_session
Role Conflicts:
unanimous strategy for strict access control:
security:
access_decision_manager:
strategy: unanimous
OIDC Discovery:
Deprecated Methods:
eraseCredentials() (removed in v7.3+); use PasswordAuthenticatedUserInterface instead.How can I help you explore Laravel packages today?