我想实现一个基于Annotations的Authorization FrontController插件,就像ASP.NET Mvc一样。 我以为我可以编写一个前端控制器插件,并将授权检查添加到Zend Framework提供的一个Hook中。例如:
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,以确定用户前往的操作是否需要授权。 事实证明并非如此简单:Request Object是唯一传递给Hooks的资源。
我以为我可以通过执行controllerName +“Controller”来构建控制器的类名,但是类没有自动加载,因此找不到它并且代码会崩溃。
任何想法?
答案 0 :(得分:0)
正如您在对问题的评论中所述,调度员可以访问实际控制器实例 - 而不仅仅是控制器名称。
可以访问控制器实例的另一个地方是action helper,它可以访问控制器实例。那么也许是一个带有preDispatch()
钩子的动作助手,可以执行基于反射的docblock内省?可能会有一些性能受到影响,因为反射被认为很慢。
但是,一般来说,这听起来像是你想要访问控制,通常使用Zend_Acl
处理,然后编写一个利用该ACL对象的控制器插件。除非您确实需要对ACL的docblock注释进行基于反射的检查,否则我将使用ACL /插件方法。
答案 1 :(得分: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"