2

我编写了一个注释,当 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

编辑:

服务.yml

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

3 回答 3

2

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

因为我们只使用@Secure来自 JMS\SecurityExtraBundle 的注解,所以我让我们的代码库改用LswSecureControllerBundle

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

于 2013-09-18T16:21:06.817 回答
1

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

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

根据作者的解决方案是使用 AOP(JMSAopBundle 提供的工具)重写或使用ClassUtils::getUserClass.

于 2012-12-14T05:46:01.430 回答
0

感谢 suihock 指出这一点:

$class = \CG\Core\ClassUtils::getUserClass($controller[0]);
$method = new \ReflectionMethod($class, $controller[1]);
于 2013-01-15T18:07:48.740 回答