diff --git a/components/security/authorization.rst b/components/security/authorization.rst index 4bac0b42c74..33e2efb9b9c 100644 --- a/components/security/authorization.rst +++ b/components/security/authorization.rst @@ -19,7 +19,7 @@ by an instance of :class:`Symfony\\Component\\Security\\Core\\Authorization\\Acc An authorization decision will always be based on a few things: * The current token - For instance, the token's :method:`Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface::getRoles` + For instance, the token's :method:`Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface::getRoleNames` method may be used to retrieve the roles of the current user (e.g. ``ROLE_SUPER_ADMIN``), or a decision may be based on the class of the token. * A set of attributes @@ -127,7 +127,7 @@ RoleVoter The :class:`Symfony\\Component\\Security\\Core\\Authorization\\Voter\\RoleVoter` supports attributes starting with ``ROLE_`` and grants access to the user when the required ``ROLE_*`` attributes can all be found in the array of -roles returned by the token's :method:`Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface::getRoles` +roles returned by the token's :method:`Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface::getRoleNames` method:: use Symfony\Component\Security\Core\Authorization\Voter\RoleVoter; @@ -167,24 +167,8 @@ role:: Roles ----- -Roles are objects that give expression to a certain right the user has. The only -requirement is that they must define a ``getRole()`` method that returns a -string representation of the role itself. To do so, you can optionally extend -from the default :class:`Symfony\\Component\\Security\\Core\\Role\\Role` class, -which returns its first constructor argument in this method:: - - use Symfony\Component\Security\Core\Role\Role; - - $role = new Role('ROLE_ADMIN'); - - // shows 'ROLE_ADMIN' - var_dump($role->getRole()); - -.. note:: - - Most authentication tokens extend from :class:`Symfony\\Component\\Security\\Core\\Authentication\\Token\\AbstractToken`, - which means that the roles given to its constructor will be - automatically converted from strings to these simple ``Role`` objects. +Roles are strings that give expression to a certain right the user has. The only +requirement is that they must start with the ``ROLE_`` prefix. Using the Decision Manager -------------------------- diff --git a/security/impersonating_user.rst b/security/impersonating_user.rst index 354be149011..d7cb59046ee 100644 --- a/security/impersonating_user.rst +++ b/security/impersonating_user.rst @@ -98,11 +98,17 @@ to show a link to exit impersonation: Finding the Original User ------------------------- +versionadded:: 4.3 + + The ``SwitchUserToken`` class was introduced in Symfony 4.3. + In some cases, you may need to get the object that represents the impersonator -user rather than the impersonated user. Use the following snippet to iterate -over the user's roles until you find one that is a ``SwitchUserRole`` object:: +user rather than the impersonated user. When a user is impersonated the token +stored in the token storage will be a ``SwitchUserToken`` instance. Use the +following snippet to obtain the original token which gives you access to +the impersonator user:: - use Symfony\Component\Security\Core\Role\SwitchUserRole; + use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken use Symfony\Component\Security\Core\Security; // ... @@ -119,14 +125,13 @@ over the user's roles until you find one that is a ``SwitchUserRole`` object:: { // ... - if ($this->security->isGranted('ROLE_PREVIOUS_ADMIN')) { - foreach ($this->security->getToken()->getRoles() as $role) { - if ($role instanceof SwitchUserRole) { - $impersonatorUser = $role->getSource()->getUser(); - break; - } - } + $token = $this->security->getToken(); + + if ($token instanceof SwitchUserToken) { + $impersonatorUser = $token->getOriginalToken()->getUser(); } + + // ... } } @@ -221,24 +226,17 @@ Create the voter class:: } if (in_array('ROLE_CUSTOMER', $subject->getRoles()) - && $this->hasSwitchToCustomerRole($token)) { + && in_array('ROLE_SWITCH_TO_CUSTOMER', $token->getRoleNames(), true)) { return true; } return false; } + } - private function hasSwitchToCustomerRole(TokenInterface $token) - { - foreach ($token->getRoles() as $role) { - if ($role->getRole() === 'ROLE_SWITCH_TO_CUSTOMER') { - return true; - } - } +.. versionadded:: 4.3 - return false; - } - } + The ``getRoleNames()`` method was introduced in Symfony 4.3. To enable the new voter in the app, register it as a service and :doc:`tag it ` with the ``security.voter``