Конфликт пользовательской аннотации с @secure из jms/SecurityExtraBundle

Я написал аннотацию, которая выдает исключение AccesDeniedException, когда действие не вызывается запросом AJAX (XMLHttpRequest).

Это работает, но когда я хочу использовать аннотацию @Secure(roles="A") из JMS/SecurityExtraBundle, она не работает, как будто я пропустил свое собственное исключение.

Контроллер

namespace Mendrock\Bundle\SagaBundle\Controller;

use JMS\SecurityExtraBundle\Annotation\Secure;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Mendrock\Bundle\SagaBundle\Entity\Saison;
use Mendrock\Bundle\SagaBundle\Form\SaisonType;
use Mendrock\Bundle\ExtraBundle\Annotation\XmlHttpRequest;


/**
* @Route("/episodesAjax")
*/
class EpisodeController extends Controller {
    /**
     * @XmlHttpRequest()
     * @Secure(roles="ROLE_SUPER_ADMIN")
     * 
     * @Route("/saisonAdd", options={"expose"=true})
     * @Template()
     */
    public function saisonAddAction() {
        $entity = new Saison();
        $form = $this->createForm(new SaisonType(), $entity);

        return array(
            'entity' => $entity,
            'form' => $form->createView(),
        );
    }

Аннотация

namespace Mendrock\Bundle\ExtraBundle\Annotation;

use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

/**
 * @Annotation
 */
class XmlHttpRequest 
{
    public $message = 'The action could be an XMLHttpRequest call.';

    public function checkRequest($event){
        if (!$event->getRequest()->isXmlHttpRequest()) {
            throw new AccessDeniedHttpException($this->message);
        }
    }

    public function execute($event){
        $this->checkRequest($event);
    }
}

Слушатель

namespace Mendrock\Bundle\ExtraBundle\Listener;

use Doctrine\Common\Annotations\Reader;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Mendrock\Bundle\ExtraBundle\Annotation\XmlHttpRequest;

class EventListener {

    private $reader;

    public function __construct(Reader $reader) {
        $this->reader = $reader;
    }

    /**
     * This event will fire during any controller call
     */
    public function onKernelController(FilterControllerEvent $event) {

        if (!is_array($controller = $event->getController())) { 
            return;
        }
        $method = new \ReflectionMethod($controller[0], $controller[1]);

        foreach ($this->reader->getMethodAnnotations($method) as $configuration) {
            if ($configuration instanceof XmlHttpRequest) {
                $configuration->execute($event);
            }
        }
    }
}

Любая идея, почему я не могу использовать одновременно @Secure(...) и @XMLHttpRequest?

Редактировать:

services.yml

services:
    annotations.xmlhttprequest:
        class: Mendrock\Bundle\ExtraBundle\Listener\EventListener
        tags: [{name: kernel.event_listener, event: kernel.controller, method: onKernelController}]
        arguments: [@annotation_reader]

person manu    schedule 20.08.2012    source источник
comment
Привет, пожалуйста, также включите свою конфигурацию для загрузки ControllerListener в качестве службы/слушателя   -  person AdrienBrault    schedule 21.08.2012


Ответы (3)


Я столкнулся с той же проблемой, когда хотел добавить свои собственные аннотации. Решение с использованием ClassUtils::getUserClass не будет работать (используя Symfony 2.3, если это имеет значение).

Поскольку мы используем только аннотацию @Secure из JMS\SecurityExtraBundle, я сделал так, чтобы наша кодовая база использовала LswSecureControllerBundle. вместо.

Этот пакет предоставляет только @Secure и не делает фокусы вуду с вашими контроллерами.

person michel v    schedule 18.09.2013

Я столкнулся с той же проблемой после обновления до Symfony 2.1.

Проблема, согласно моему исследованию, заключается в том, что JMS SecurityExtraBundle генерирует прокси-классы всякий раз, когда вы используете одну из их аннотаций. Проблема с созданными прокси-классами заключается в том, что пользовательские аннотации не передаются через прокси, поэтому аннотации кажутся отсутствующими.

решение, по мнению автора, заключается в переписывании с использованием АОП (возможности, предоставляемые от JMSAopBundle) или использовать ClassUtils::getUserClass.

person dteoh    schedule 14.12.2012
comment
Итак, как мы можем это сделать? Нам нужно сделать другой прокси? Я также попытаюсь решить свою проблему с парадигмой aop. - person manu; 14.12.2012
comment
Я спросил автора JMSSecurityExtraBundle и обновил свой ответ ссылкой на его решение. - person dteoh; 15.12.2012

Спасибо suihock за указание на это:

$class = \CG\Core\ClassUtils::getUserClass($controller[0]);
$method = new \ReflectionMethod($class, $controller[1]);
person coma    schedule 15.01.2013