2011-09-11 7 views
0

ASP.NET MvcのようにAnnotationに基づくAuthorization FrontController Pluginを実装したかったのです。 フロントコントローラープラグインを作成し、Zend Frameworkが提供するフックの1つにAuthorizationチェックを追加することができたと思います。例:Zend Framework Inspect Controllerクラスのdocblockタグ

class My_Controller_Plugin_Authorize extends Zend_Controller_Plugin_Abstract { 
    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request){ 
     ... 
     if($user_is_not_loggedin){ 
      goSomeWhereElse(); 
     } 
    } 
} 

class MyFancyController extends Zend_Controller_Action{ 

    /** 
    * @Authorize 
    */ 
    public function secretAction(){ 
     ... 
    } 
} 

は今、私はユーザーが向かっているアクションが許可かないことを要求するかどうかを調べるには、実際の要求されたコントローラでにdocblockを検査する必要があります。 それほど単純ではないことが判明しました。要求オブジェクトは、フックに渡される唯一のリソースです。

私はcontrollerName + "Controller"を実行してコントローラのクラス名を構築できると思っていましたが、クラスがオートロードされないため、コードが見つからず、コードが破損します。

すべてのアイデア?

+0

に、私は実際にZendFrameworkクラスで掘り解決策を見つけた: $ frontController = Zend_Controller_Frontを::のgetInstance(); $ dispatcher = $ frontController-> getDispatcher(); $ controllerClass = $ディスパッチャ - > getControllerClass($リクエスト); $ dispatcher-> loadClass($ controllerClass); $ annotation = new Zend_Reflection_Docblock(新しいZend_Reflection_Class($ controllerClass)); 今のように見えますが、パフォーマンスについては何も分かりません – user711643

+0

反射は遅いですが、「遅い」は相対的です。ベンチマークを実行して問題が発生するかどうかを確認し、問題がある場合はキャッシングを検討してください。 –

答えて

0

、あなたの質問にあなたのコメントに注意しているように、ディスパッチャは、実際のコントローラインスタンスへのアクセス権を持っている - ちょうどコントローラ名前とは対照的です。

コントローラインスタンスにアクセスできる別の場所は、コントローラインスタンスにアクセスできるaction helperです。だからおそらくpreDispatch()フックのアクションヘルパーは、反射ベースのdocblockのイントロスペクションを実行する?反射が遅いと考えられるため、おそらくパフォーマンスが低下します。

しかし、通常、これはアクセス制御が必要なように聞こえますが、通常はZend_Aclを使用して処理され、そのACLオブジェクトを使用するコントローラプラグインを作成します。 本当にがあなたのACL用のdocblock注釈の反映ベースの検査を行う必要がない限り、私はACL /プラグインのアプローチに行きます。

0

これは私の解決です。 @Authorizeアノテーションは、クラスの上部または単一のメソッドの最上部で機能します。 明らかにACLで確認するように拡張することができます。

<?php 
class Ant_Controller_Plugin_Authorize extends Zend_Controller_Plugin_Abstract { 

    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request){ 
     $frontController = Zend_Controller_Front::getInstance(); 
     $dispatcher = $frontController->getDispatcher(); 
     $controllerClass = $dispatcher->getControllerClass($request); 
     $dispatcher->loadClass($controllerClass); 
     $reflectionClass = new Zend_Reflection_Class($controllerClass); 
     $reflectionMethod = $reflectionClass->getMethod($dispatcher->getActionMethod($request)); 
     try { 
      $authClass = $reflectionClass->getDocblock()->hasTag("Authorize"); 
     } catch (Exception $e) { 
      $authClass = false; 
     } 
     try{ 
      $authMethod = $reflectionMethod->getDocblock()->hasTag("Authorize"); 
     }catch (Exception $e){ 
      $authMethod = false; 
     } 

     if($authClass || $authMethod){ 
      if(!Zend_Auth::getInstance()->hasIdentity()){ 
       $request->setActionName("login")->setControllerName("Accounts"); 
       $request->setDispatched(false); 
      } 
     } 
    } 
} 

、その後のapplication.ini

resources.frontController.plugins.Authorize = "Ant_Controller_Plugin_Authorize"