From d13e9f1f439f7fbf5eef7a123dbbe9575cc275bc Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 15 Sep 2025 12:43:18 +0200 Subject: [PATCH] [Security] Add `access_decision()` and `access_decision_for_user()` --- security.rst | 64 +++++++++++++++++++++++++++++++++++++++++++++ security/voters.rst | 2 ++ 2 files changed, 66 insertions(+) diff --git a/security.rst b/security.rst index 50e33402188..0c3df87de10 100644 --- a/security.rst +++ b/security.rst @@ -2591,6 +2591,34 @@ the built-in ``is_granted_for_user()`` helper function: Delete {% endif %} +Symfony also provides the ``access_decision()`` and ``access_decision_for_user()`` +Twig functions to check authorization and to retrieve the reasons for denying +permission in :ref:`your custom security voters `: + +.. code-block:: html+twig + + {% set voter_decision = access_decision('post_edit', post) %} + {% if voter_decision.isGranted() %} + {# ... #} + {% else %} + {# before showing voter messages to end users, make sure it's safe to do so #} +

{{ voter_decision.message }}

+ {% endif %} + + {% set voter_decision = access_decision('post_edit', post, anotherUser) %} + {% if voter_decision.isGranted() %} + {# ... #} + {% else %} +

The {{ anotherUser.name }} user doesn't have sufficient permission:

+ {# before showing voter messages to end users, make sure it's safe to do so #} +

{{ voter_decision.message }}

+ {% endif %} + +.. versionadded:: 7.4 + + The ``access_decision()`` and ``access_decision_for_user()`` Twig functions + were introduced in Symfony 7.4. + .. _security-isgrantedforuser: Securing other Services @@ -2642,6 +2670,42 @@ want to include extra details only for users that have a ``ROLE_SALES_ADMIN`` ro The :method:`Symfony\\Bundle\\SecurityBundle\\Security::isGrantedForUser` method was introduced in Symfony 7.3. +You can also use the ``getAccessDecision()`` and ``getAccessDecisionForUser()`` +methods to check authorization and get to retrieve the reasons for denying +permission in :ref:`your custom security voters `:: + + // src/SalesReport/SalesReportManager.php + + // ... + use Symfony\Bundle\SecurityBundle\Security; + + class SalesReportManager + { + public function __construct( + private Security $security, + ) { + } + + public function generateReport(): void + { + $voterDecision = $this->security->getAccessDecision('ROLE_SALES_ADMIN'); + if ($voterDecision->isGranted('ROLE_SALES_ADMIN')) { + // ... + } else { + // do something with $voterDecision->getMessage() + } + + // ... + } + + // ... + } + +.. versionadded:: 7.4 + + The ``getAccessDecision()`` and ``getAccessDecisionForUser()`` methods + were introduced in Symfony 7.4. + If you're using the :ref:`default services.yaml configuration `, Symfony will automatically pass the ``security.helper`` to your service thanks to autowiring and the ``Security`` type-hint. diff --git a/security/voters.rst b/security/voters.rst index e621263abb4..803715ea4dc 100644 --- a/security/voters.rst +++ b/security/voters.rst @@ -124,6 +124,8 @@ calls out to the "voter" system. Right now, no voters will vote on whether or no the user can "view" or "edit" a ``Post``. But you can create your *own* voter that decides this using whatever logic you want. +.. _creating-the-custom-voter: + Creating the custom Voter -------------------------