Symfony security annotation on controller class and inherited action method

Symfony security extension annotation class and methodThis is a quick code example on how to extend the Symfony security extension in your bundle so you could have rules on the controller’s class as annotation and also inherit those and merge with the action method annotations.

namespace AppBundle\Configuration;

/**
 * @Annotation
 */
class Security extends \Sensio\Bundle\FrameworkExtraBundle\Configuration\Security
{
    public function getAliasName()
    {
        return 'app_security';
    }

    public function allowArray()
    {
        // allow nested configuration (class/method).
        return true;
    }
}
Security.php

This class allow you compound the final security expression through all security configurations class and method.

namespace AppBundle\Configuration;

class SecurityConfiguration
{
    /**
     * @var Security[]
     */
    private $configurations;

    public function __construct(array $configurations)
    {
        $this->configurations = $configurations;
    }

    public function getExpression()
    {
        $expressions = [];
        foreach ($this->configurations as $configuration) {
            $expressions[] = $configuration->getExpression();
        }

        return implode(' and ', $expressions);
    }
}
SecurityConfiguration.php
namespace AppBundle\EventListener;

use AppBundle\Configuration\SecurityConfiguration;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class SecurityListener extends \Sensio\Bundle\FrameworkExtraBundle\EventListener\SecurityListener
{
    public function onKernelController(FilterControllerEvent $event)
    {
        $request = $event->getRequest();
        if (!$configuration = $request->attributes->get('_app_security')) {
            return;
        }

        // trick to simulate one security configuration (all in one class/method).
        $request->attributes->set('_security', new SecurityConfiguration($configuration));

        parent::onKernelController($event);
    }

    public static function getSubscribedEvents()
    {
        // this listener must be called after Sensio\Bundle\FrameworkExtraBundle\EventListener\ControllerListener.
        return array(KernelEvents::CONTROLLER => array('onKernelController', -1));
    }
}
SecurityListener.php
services:
    app.security.listener:
        class: AppBundle\EventListener\SecurityListener
        parent: sensio_framework_extra.security.listener
        tags:
            - { name: kernel.event_subscriber }
services.yml

Finally, just use your @AppBundle\Configuration\Security annotation instead the standard one.

It's only fair to share...Buffer this pageShare on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0Share on Reddit0Pin on Pinterest0Email this to someone
About

Just a guy with strong interest in PHP and Web technologies

Posted in PHP, Symfony2 Tagged with: , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*