自定义注释与来自jms / SecurityExtraBundle的@secure冲突

时间:2012-08-20 15:34:46

标签: php symfony annotations

我编写了一个注释,当AJAX请求(XMLHttpRequest)未调用该操作时,该注释会抛出AccesDeniedException。

它可以工作,但是当我想使用JMS / SecurityExtraBundle中的@Secure(roles =“A”)注释时,它不能像我省略我的自定义异常那样工作。

控制器

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]

2 个答案:

答案 0 :(得分:2)

当我想添加自己的注释时遇到了同样的问题。使用ClassUtils::getUserClass的解决方案不起作用(使用Symfony 2.3,如果这有所不同)。

由于我们只使用JMS \ SecurityExtraBundle中的@Secure注释,因此我使用LswSecureControllerBundle替代了代码库。

此捆绑包仅提供@Secure,并且不会对您的控制器执行voodoo技巧。

答案 1 :(得分:1)

升级到Symfony 2.1后,我遇到了同样的问题。

从我的调查来看,问题是JMS SecurityExtraBundle会在您使用其中一个注释时生成代理类。生成的代理类的问题是自定义注释不会被代理,这就是注释似乎丢失的原因。

根据作者的solution是使用AOP(JMSAopBundle提供的设施)重写或使用ClassUtils::getUserClass