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ますか?

編集:

services.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 を使用します)。

@SecureJMS\SecurityExtraBundleのアノテーションのみを使用するため、代わりにコードベースでLswSecureControllerBundleを使用するようにしました。

このバンドルは を提供するだけ@Secureで、コントローラーでブードゥーのトリックを行うわけではありません。

于 2013-09-18T16:21:06.817 に答える
0

これを指摘してくれた suihock に感謝します。

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