Security
Symfony's Security component handles two related but distinct questions for every request: authentication ("who are you?") and authorization ("what are you allowed to do?"). Authentication figures out the identity behind a request — usually by checking a login session or token — while authorization decides whether that identity is permitted to reach a particular route or perform a particular action.
The security.yaml Configuration File
Most of the Security component's setup lives in config/packages/security.yaml. It
defines the application's firewalls (which URL patterns require authentication
and how), its user providers (where user accounts are loaded from, such as the
Doctrine-mapped User entity), and the password hashing algorithm
used for stored passwords. You won't hand-write most of this — Symfony Flex generates a working
starting point when you install the security package — but knowing what lives here helps when
something needs adjusting.
security:
password_hashers:
App\Entity\User: 'auto'
firewalls:
main:
provider: app_user_provider
form_login: true
security.yaml.Protecting a Route
Once a firewall and a set of roles exist, restricting an entire controller action to a specific role is a single PHP 8 attribute — no separate configuration file needed, in the same spirit as the routing and validation attributes covered earlier in this track.
<?php
namespace App\Controller;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class ArticleController extends AbstractController
{
#[IsGranted('ROLE_ADMIN')]
public function delete(Article $article)
{
// only reached if the current user has ROLE_ADMIN
}
}
The imperative equivalent — useful when the check depends on something only known partway
through the method, such as whether the current user owns the specific article — calls
denyAccessUnlessGranted() directly inside the action:
public function delete(Article $article)
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
// execution stops here with a 403 response for anyone lacking ROLE_ADMIN
}
Getting the Current User
Inside any controller extending AbstractController, the currently authenticated
user (or null, if nobody is logged in) is available through a single method call —
no manual session lookups required.
public function profile()
{
$user = $this->getUser();
return $this->render('user/profile.html.twig', ['user' => $user]);
}
Passwords Are Never Compared in Plaintext
Whatever algorithm is configured in security.yaml, password hashing and comparison
always run through the injected PasswordHasherInterface — you hash a plaintext
password once, when it's set, and store only the hash. Logging in never compares a submitted
password to a stored password directly; it hashes the submitted value the same way and compares
hashes instead. This is a basic security principle worth carrying into any framework, and
Symfony's Security component simply automates it for you.