New in Symfony 7.3: Arbitrary User Permission Checks


Contributed by
Nate Wiebe
in
#48142
and #59129

In the Symfony security feature, the access control part decides if a user
can access some resource (a URL, a model object, a method call, etc.). This is
configured with roles and checked using the #[IsGranted] attribute, the
isGranted() PHP method, and the is_granted() Twig function.
For example, checking if a user has permissions inside a service:

// src/Reports/SalesReportGenerator.php

// ...
use Symfony\Bundle\SecurityBundle\Security;

class SalesReportGenerator
{
public function __construct(
private Security $security,
) {
}

public function generate(): void
{
if ($this->security->isGranted('ROLE_SALES_EXECUTIVE')) {
// ...
}

// ...
}
}

The isGranted() method always checks the permissions of the currently logged
in user
. This is fine most of the times, but falls short in scenarios like commands,
offline tasks, message queues, etc. That's why in Symfony 7.3 we're introducing
isGrantedForUser(), a new method to check permissions of arbitrary users:

// ...
use Symfony\Bundle\SecurityBundle\Security;

class SalesReportGenerator
{
public function __construct(
private Security $security,
) {
}

public function generate(): void
{
// get somehow all users that will receive the report...
/** @var UserInterface[] $users */
$users = ...

// you can now check permissions of all users while generating reports
foreach ($users as $user) {
if ($this->security->isGrantedForUser($user, 'ROLE_SALES_EXECUTIVE')) {
// ...
}

// ...
}
}
}

In Twig templates, use the new is_granted_for_user() function to check
permissions for any arbitrary user:

{% if is_granted('ROLE_SALES_EXECUTIVE') %}
<a href="..."> Download report a>
{% endif %}

{% if is_granted_for_user(another_user, 'ROLE_SALES_EXECUTIVE') %}
<a href="..."> Send the sales report to {{ another_user }} a>
{% endif %}

Sponsor the Symfony project.