Как использовать dump() или dd() внутри пользовательского избирателя Symfony?

Я следовал нескольким примерам из symfony, API-платформы и нескольким примерам stackoverflow, но безрезультатно. Я не знаю, то ли я делаю что-то не так, то ли я не понимаю концепции избирателя и ролей. Когда я пытался получить доступ к конечной точке, он выдает Только пользователь с правами доступа может просматривать панель инструментов.

В сервисах.yaml

app.user_permission:
        class: App\Security\SecurityVoter
        arguments: ['@security.access.decision_manager']
        tags:
            - { name: security.voter}

Я создал собственный избиратель для использования. Здесь я сделал несколько изменений, удалил несколько вещей, чтобы принять пример, который я видел в StackOverflow Пример.

use App\Entity\Product;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;


class SecurityVoter extends Voter {
        
        private $decisionManager;
        const VIEW = 'view';
        const EDIT = 'edit';

        
        public function __construct (AccessDecisionManagerInterface $decisionManager) {
            $this->decisionManager = $decisionManager;
        }
        

        protected function supports($attribute, $subject): bool {
            // if the attribute isn't one we support, return false
            if (!in_array($attribute, [self::VIEW, self::EDIT])) {
                return false;
            }
            
          return true;
           
        }
        /**
         * @param string $attribute
         * @param TokenInterface $token
         * @return bool
         */
        protected function voteOnAttribute($attribute, $object, TokenInterface $token): bool {
            $user = $token->getUser();
            
            if (!$user instanceof UserInterface) {
                // the user must be logged in; if not, deny access
                return false;
            }

            
           // check ROLE_USER 
            if ($this->security->isGranted('ROLE_USER')) {
                return true;
            }
            switch ($attribute) {
                case self::VIEW:
                    if ($this->decisionManager->decide($token, ['ROLE_USER'])) {
                        return true;
                    }
                break;
                case self::EDIT:
                    if ($this->decisionManager->decide($token, ['ROLE_USER'])) {
                        return true;
                    }
                break;

            }
            
            throw new \LogicException('This code should not be reached!');
        }
        
     
}

В моем Entity я определил что-то вроде этого.

#[ApiResource(
    attributes: ["security" => "is_granted('ROLE_USER')"],
    collectionOperations: [
        "get",
        "post" => [
            "security_post_denormalize" => "is_granted('ROLE_USER)",
            "security_message" => "Only user with permission can create a dashboard.",
        ],
    ],
    itemOperations: [
        "get" => [ "security" => "is_granted('VIEW') " , "security_message" => "Only user with permission can view dashboard."],
        "put" => [ "security" => "is_granted('EDIT')", "security_message" => "Only user with permission can edit dashboard."],
    ],
)]

В настоящее время я использую Symfony 5.4.7, и я пытался использовать пример кода. Кажется, ничего не работает. Приходится использовать dd() и dump(), ни в консоли, ни в профилировщике ничего не печаталось. Я использовал loggerInterface (возможно, я сделал это неправильно), и я не увидел, что что-то выводится в var.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
1
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы ближе, чем вы думаете. Вам не нужен используйте Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface. Вы можете использовать класс безопасности следующим образом.

use App\Entity\Product;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;


class SecurityVoter extends Voter {
        
        private $security;
        const VIEW = 'view';
        const EDIT = 'edit';

        
        public function __construct ( Security $security) {
            $this->security = $security;
        }
        

        protected function supports($attribute, $subject): bool {
            // if the attribute isn't one we support, return false
            $supportsAttribute = in_array($attribute, ['VIEW', 'EDIT']);
            $supportsSubject = $subject instanceof WorkshopSession;
    
            return $supportsAttribute && $supportsSubject;
           
        }
        /**
         * @param string $attribute
         * @param Product $product
         * @param TokenInterface $token
         * @return bool
         */
        protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool {
            $user = $token->getUser();
            
            if (!$user instanceof UserInterface) {
                // the user must be logged in; if not, deny access
                return false;
            }

         
           
            dd($user);

           // check ROLE_USER 
            if ($this->security->isGranted('ROLE_USER')) {
                return true;
            }
            switch ($attribute) {
                case self::VIEW:
                    if ($this->security->isGranted('ROLE_USER')) {
                        return true;
                    }
                break;
                case self::EDIT:
                    if ($this->security->isGranted('ROLE_USER')) {
                        return true;
                    }
                break;

            }
            
            throw new \LogicException('This code should not be reached!');
        }
        
     
}

При этом вам не нужно настраивать сервис для этого.

Чтобы внедрить избиратель в уровень безопасности, вы должны объявить его как службу и пометить его с помощью security.voter. Но если вы используете конфигурацию services.yaml по умолчанию, это делается автоматически!

В вашей сущности

#[ApiResource(
    attributes: ["security" => "is_granted('ROLE_USER')"],
    collectionOperations: [
        "get",
        "post" => [
            "security_post_denormalize" => "is_granted('ROLE_USER')",
            "security_message" => "Only user with permission can create a dashboard.",
        ],
    ],
    itemOperations: [
        "get" => [ "security" => "is_granted('VIEW', object) " ],
        "put" => [ "security" => "is_granted('EDIT')", "security_message" => "Only user with permission can edit dashboard."],
    ],
)]

Вы также можете прочитать это для справки - Платформа API

ПРИМЕЧАНИЕ: вы можете использовать dd() - например. дд ($ пользователь);

Другие вопросы по теме