Symfony authorization = roles
Symfony’s authorization system is based on roles and is essentially is a two-step process:
- You assign one or more roles to a given user.
- You grant/deny access to resources (e.g., URLs or files) based on the user’s roles.
Roles in action
You’ll want to add a user.roles
column which contains a JSON array of role names. So something like:
// src/Entity/User.php
// ...
class User
{
#[ORM\Column(type: 'json')]
private array $roles = [];
// ...
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
}
You can then grant / deny access based on the roles via:
- Access control rules in
security.yaml
- Custom logic in your controller code
- Attributes
1. Access control rules
# config/packages/security.yaml
security:
# ...
firewalls:
# ...
main:
# ...
access_control:
# require ROLE_ADMIN for /admin*
- { path: '^/admin', roles: ROLE_ADMIN }
# or require ROLE_ADMIN or IS_AUTHENTICATED_FULLY for /admin*
- { path: '^/admin', roles: [IS_AUTHENTICATED_FULLY, ROLE_ADMIN] }
# the 'path' value can be any valid regular expression
# (this one will match URLs like /api/post/7298 and /api/comment/528491)
- { path: ^/api/(post|comment)/\d+$, roles: ROLE_USER }
2. Controller code
// src/Controller/AdminController.php
// ...
public function adminDashboard(): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
// or add an optional message - seen by developers
$this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'User tried to access a page without having ROLE_ADMIN');
}
3. Attributes
// src/Controller/AdminController.php
// ...
use Symfony\Component\Security\Http\Attribute\IsGranted;
#[IsGranted('ROLE_ADMIN')]
class AdminController extends AbstractController
{
// Optionally, you can set a custom message that will be displayed to the user
#[IsGranted('ROLE_SUPER_ADMIN', message: 'You are not allowed to access the admin dashboard.')]
public function adminDashboard(): Response
{
// ...
}
}
If access isn’t granted, a AccessDeniedException
will be thrown.
Other notes
Role hierarchy
You can create role hierarchies using config/packages/security.yaml
:
# config/packages/security.yaml
security:
# ...
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
In the example config from above:
- Users with the role
ROLE_ADMIN
will have the roleROLE_USER
- Users with the role
ROLE_SUPER_ADMIN
will have the roleROLE_ADMIN
,ROLE_ROLE_ALLOWED_TO_SWITCH
, andROLE_USER