2017-07-05 4 views
0

/adminルートへのアクセスを保護するために私のアプリケーションでZfcUserモジュールを使用しています。私はそうするためにはzfcuser - ホワイトリストのルートとすべての子ルート

/ログインを除き、/登録など、/管理のすべてchildroutesをブロックするように、私はここに受け入れ答えからコードを追加しました - Zend Framework 2 - Global check for authentication with ZFCUser

protected $whitelist = array('zfcuser/login', 'default'); 

    public function onBootstrap($e) 
    { 
     $app = $e->getApplication(); 
     $em = $app->getEventManager(); 
     $sm = $app->getServiceManager(); 

     $list = $this->whitelist; 
     $auth = $sm->get('zfcuser_auth_service'); 

     $em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($list, $auth) { 
      $match = $e->getRouteMatch(); 

      // No route match, this is a 404 
      if (!$match instanceof RouteMatch) { 
       return; 
      } 

      // Route is whitelisted 
      $name = $match->getMatchedRouteName(); 
      if (in_array($name, $list)) { 
       return; 
      } 

      // User is authenticated 
      if ($auth->hasIdentity()) { 
       return; 
      } 

      // Redirect to the user login page, as an example 
      $router = $e->getRouter(); 
      $url  = $router->assemble(array(), array(
       'name' => 'zfcuser/login' 
     )); 

      $response = $e->getResponse(); 
      $response->getHeaders()->addHeaderLine('Location', $url); 
      $response->setStatusCode(302); 

      return $response; 
     }, -100); 
    } 

それしかし、ルートルートへのアクセスもブロックされます。その多くが存在するため、ホワイトリストにすべてのルートを追加することは本当にありません。/adminルートへのアクセスを制限する方法はありますか?

答えて

1

あなたは、各コントローラの名前を確認する代わりに、ルート名をチェックして管理領域へのアクセスを保護することができます。したがって、ユーザーのアクセスをより簡単に制御でき、ルート名を確認するよりも移植性が向上します。

アクセスを制限するコントローラを一覧表示します。したがって、コントローラに関連するすべてのものを制限する必要があります。アクセスを制限する必要がある場合は、ここにリストしてください。もうonBootstrap()メソッドで手を汚す必要はありません。

protected $whitelist = array(
    'ZfcUser\Controller\User', // or use 'zfcuser' 
); 

右コントローラ名を$whitelistに入れます。 onBootstrap()メソッドで$controllerをエコーすることでそれを得ることができます。下記のコメント欄をご覧ください。

次はコントローラー名をキャッチし、そのリストにリストされているかどうかを確認します。

public function onBootstrap(MvcEvent $e) 
{ 
    $app = $e->getApplication(); 
    $em = $app->getEventManager(); 
    $sm = $app->getServiceManager(); 

    $list = $this->whitelist; 
    $auth = $sm->get('zfcuser_auth_service'); 

    $em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($list, $auth) { 

     // get the current route 
     $route = $e->getRouteMatch()->getMatchedRouteName(); 

     // check for 'zfcuser/login' and 'zfcuser/register' routes 
     if (in_array($route, array('zfcuser/login', 'zfcuser/register'))) { 
      return; 
     } 

     // get the current controller name 
     $controller = $e->getRouteMatch()->getParam('controller'); 

     // Check the right controller name by echoing 
     // echo $controller;   

     // check if a user has access on the current controller 
     if (in_array($controller, $list)) { 

      if(! $auth->hasIdentity()) { 

       $router = $e->getRouter(); 
       $url = $router->assemble(array(), array(
        'name' => 'zfcuser/login' 
       )); 

       $response = $e->getResponse(); 
       $response->getHeaders()->addHeaderLine('Location', $url); 
       $response->setStatusCode(302); 

       return $response; 
      } 
     } 

    }, -100); 
}  

お手伝いがあればお知らせください。

+0

ええ、この解決法はこれまでのところ仕事をしています!明確な説明のおかげで、あなたはもう一度私を救う:-) – ficus

+0

いつでも歓迎です! :) – unclexo

1

/adminルートへのアクセスのみを制限する方法はありますか?本当にかなりリストよりも、あなたがリストを必要とするか、条件付きのチェックのロジックを変更することを意味します

要件に応じて、ルートの一部だけを確認することができます。

$this->whitelist = [ 
    'zfcuser/login', 
    'default' 
]; 

// Route is whitelisted 
$currentRoute = $match->getMatchedRouteName(); 

foreach($this->whitelist as $route) { 
    if (0 === strpos($currentRoute, $route)) { 
     // we matched the start of the route, 
     // e.g every route under 'default' would match this 
     return; 
    } 
} 
+0

ブラックリストもホワイトリストも、すべての単一の子供のルートを入力する必要があるため、この場合は適切な解決策ではありません。 あなたのソリューションは、strpos($ currentRoute、$ route)の変数の場所を変更した後に動作しているように見えますが、テストしたところでは何か不思議なことがあります。このトピックを更新して、それをさらに調査します。 ありがとうございました! – ficus

+0

@ficus whoops; yes 'strpos($ currentRoute、$ route)'でなければなりません。私は私の答えを更新しました。 – AlexP

+0

いくつかのテストの後、適切に動作しますが、すべての単一ルートを一方向または別の方法で指定する必要は非常に厄介です。コントローラーを使用したソリューションがその問題を解決しました。助けてくれてありがとう、私はそれを感謝します! – ficus

0

私はZfcRbacを見てみることをお勧めします。

return [ 
    'zfc_rbac' => [ 
     'guards' => [ 
      'ZfcRbac\Guard\RouteGuard' => [ 
       'admin*' => ['admin'] 
      ] 
     ] 
    ] 
]; 

これはadmin役割のユーザーにadminで始まる任意の経路を制限します:それは私はあなたが探しているまさにだと思う"guards" functionalityを持っています。デフォルト動作モードはブラックリストベース(「保護モード」は「許可」)なので、アクセスを制限するルートのルールを指定する必要があります。 RouteGuardに一致しないルートはすべて公開されます。

関連する問題