2016-03-15 21 views
1

我有以下設置:的Symfony:如何觸發自定義安全選民對動態路由

  • 動態路由裝載機其中genrates路線,並呼籲基於信息從數據庫中有關應用程序的意見

  • 定製適當的控制器安全選民從而驗證用戶是否有權訪問當前視圖

我當然可以調用is_gran的從適當的控制器內部運行方法。我想做的事情是,不要從控制器內部觸發選舉器(這需要在每個控制器中重複一次,只是使用不同的視圖ID),而是爲路由加載器中生成的每條路由自動觸發選舉器。這樣我就不必執行標準驗證,這對每條路線基本相同 - 檢查用戶是否有權訪問此視圖,但關注業務邏輯,這可能需要額外的要求才能滿足用戶訪問此路線的權限(並且此是什麼在控制器中)。

我會在方向有一些參數線路生成方法:

$route = new Route($path, $defaults, $requirements); 

    $routes->add($routeName, $route); 

這將讓我觸發is_granted有關參數創建的路線,但文檔是稀少。

有誰知道如何將這種要求傳遞給用戶例如。爲創建的路線要求用戶is_granted('VIEW_1')

回答

2

你可以添加任何你想要的默認數組,他們會傳遞。例如:

cerad_game__project__game__update__by_scorer: 
    path: /project/{_project}/game/{_game}/update-by-scorer 
    defaults: 
    _role:  ROLE_SCORER_ADMIN 
    _model:  cerad_game__project__game__update__by_scorer__model_factory 
    _form:  cerad_game__project__game__update__by_scorer__form_factory 
    _controller: cerad_game__project__game__update__by_scorer__controller:action 
    _template: '@CeradGame/Project/Game/Update/ByScorer/GameUpdateByScorerTwigPage.html.twig' 

你會再創建一個內核控制器監聽控制器解決後,將被調用,但該控制器的操作方法被調用之前。

class ModelEventListener extends ContainerAware implements EventSubscriberInterface { 

public static function getSubscribedEvents() 
{ 
    return array(
     KernelEvents::CONTROLLER => array( 
      array('onControllerRole', self::ControllerRoleEventListenerPriority), 
      array('onControllerModel', self::ControllerModelEventListenerPriority), 
      array('onControllerForm', self::ControllerFormEventListenerPriority), 
     ), 
     KernelEvents::VIEW => array(
      array('onView', self::ViewEventListenerPriority), 
     ), 
    ); 
} 

public function onControllerRole(FilterControllerEvent $event) 
{ 
    if (!$event->getRequest()->attributes->has('_role')) return; 

    $role = $event->getRequest()->attributes->get('_role'); 

    $securityContext = $this->container->get('security.context'); 

    if (!$securityContext->isGranted($role)) 
    { 
     // For public it redirects 
     // For users we see the exception 
     // die('access denied ' . $event->getRequest()->attributes->get('_route')); 
     throw new AccessDeniedException(); 
    } 
} 

再用鐵絲起來:

cerad_core__model_event_listener: 
    class: '%cerad_core__model_event_listener__class%' 
    calls: 
     - [setContainer, ['@service_container']] 
    tags: 
     - { name: kernel.event_subscriber } 

這裏記載:http://symfony.com/doc/current/cookbook/event_dispatcher/event_listener.html

請注意,我在這裏注入,而不是僅僅的安全上下文的容器。我需要其他方法的容器。它也是2.7代碼。還沒有到處去更新到3.0呢。

+0

非常感謝。絕對正確的解決方案和優雅的一般方法。我對使用Route param的想法如此固定,以至於我需要微調才能看到正確的方式;) – StormoPL