【问题标题】:Using Zend_Auth to secure all controllers使用 Zend_Auth 保护所有控制器
【发布时间】:2011-02-09 10:59:45
【问题描述】:

我将如何全局保护我的所有控制器(除了我的登录控制器)以确保我的应用程序在所有方面都是安全的(没有隐藏的 ajax 调用后门等)。我以为我可以把它放在我的引导文件中,但这感觉不对?我试图避免向每个控制器添加任何代码。

建议?

【问题讨论】:

    标签: php security zend-framework


    【解决方案1】:

    编辑:这是对@singles 响应的补充。

    您必须了解有两种不同的东西。 AuthAcl。 Auth 告诉您谁是用户,例如,您可以将没有 Auth 的用户重定向到您的登录控制器,并在登录后设置一个 auth 身份。然后 Acl 系统根据 Auth 数据(可能是用户 ID 或角色,存储在 Auth 存储中)做出是/否决定。

    一个不错的解决方案是拥有 2 个控制器插件(在引导程序上以良好的顺序注册,Auth 然后 Acl)。如果您不使用控制器插件,则必须在需要时在每个控制器中调用 Acl 检查。如果您总是需要它,请使用插件。

    在您的Auth 插件 中实现preDispatch() 以设置例如匿名身份,如果您没有从Zend_Auth 返回身份。 这是一个真实的sn-p代码:

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $module = $request->getModuleName();
        $controller = $request->getControllerName();
        $action = $request->getActionName();
        $auth = Zend_Auth::getInstance();
        if (!$auth->hasIdentity()) {
            // set a default anonymous identity
            $auth->getStorage()->write(array('name' => 'anonymous','role' => 1,));
        }
    (...)
    

    对于Acl 控制器插件,任务也在preDispatch() 中。您可以为每个请求的 url 启动 acl 检查(因此对于每个用户请求,甚至是 ajax)。这是一个部分的 sn-p,所以这只是你如何处理事情的一个例子:

    public function preDispatch(Zend_Controller_Request_Abstract $request) {
        $controller = $request->controller;
        $module = $request->module;
        $action = $request->action;
        // here you should code something nice retrieving you Zend_Acl object
        // with some caching options maybe, building roles, ressources, etc
        $this->_acl = $this->getAcl(); 
        if (!$this->_acl->isCurrentUserAllowed($module,'see')) {
            $auth = Zend_Auth::getInstance();
        $identity  = $auth->hasIdentity('identity')? $auth->getIdentity() : null;
        if(isset($identity)) {
                if($identity['name'] == 'anonymous') {
                    // WARNING: avoid infinite redirect loops on login page
                    if (!($request->getControllerName() == 'login' 
                        && $request->getActionName()=='login' 
                        && $request->getModuleName() == 'default')) {
                            $request->setControllerName('login')
                   ->setActionName('login')
                   ->setModuleName('default');
                return;
    (...)
    

    在这个系统中,最后一个重要的部分是 LoginController,如果成功登录,您应该启动身份记录:

    (...)
    $auth = Zend_Auth::getInstance();
    Zend_Session::regenerateId();
    $storage = $auth->getStorage();
    $rowobject = $authAdapter->getResultRowObject(null,'passwd');
    $storage->write((array)$rowobject);
    (...)
    

    【讨论】:

    • +1 我喜欢anonymous user 的想法,并保证我会在我的作品中使用它:)
    【解决方案2】:

    您应该为此编写 ACL 插件并将其注册到前端控制器中。如果您将此类功能实现为插件,您将可以灵活地在下一个应用程序中使用它 - 无需从自定义控制器扩展每个控制器。

    资源:
    1.Front Controller Plugins in Zend Framework - ZF 中插件的工作原理
    2. Zend_Acl / Zend_Auth example scenario - ACL 插件的许多可能实现之一。
    3. Google - 还有很多其他资源

    【讨论】:

      【解决方案3】:

      嗯,你需要有一个进入你的系统的入口点:)

      这可以通过扩展 Zend_Controller_Action 来实现,比如说:

      abstract class MyController extends Zend_Controller_Action {
        public function preDispatch(){
          // do the logic
        }
      } 
      

      现在你的每个控制器只需要扩展 MyController 就很安全了。

      【讨论】:

      • 在该解决方案中,您需要在每个应用程序中扩展自定义控制器。我认为,前端控制器插件将是更好的解决方案 - 您可以在需要时注册它,并在您想要的 ZF 应用程序中注册它,而无需修改现有代码。
      • 没错,完全同意。一旦你知道了插件,它们就是神奇的:) 支持你的解决方案。
      【解决方案4】:

      我在一个实现中的方法是在我的应用程序路径中创建一个名为 Auth.php 的文件。然后我打开了我想要保护的每个控制器并添加了这一行

      include_once APPLICATION_PATH . '/Auth.php';
      

      调用 parent::init() 之前的 init() 方法。

      至于 Auth.php 文件本身,它基本上是使用 Zend_Auth 来进行认证的。成功后,我会保存用户的身份以供以后在应用程序中使用

      $this->view->assign('myIdentity', Zend_Auth::getInstance()->getIdentity());
      

      如果失败,我会重定向到登录页面并传递一些参数,以便登录页面在我登录后知道将我发送到哪里。

      这不是一个优雅的解决方案,但它可靠且相对快速且易于实施。

      【讨论】:

        猜你喜欢
        • 2014-04-23
        • 2016-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-16
        • 1970-01-01
        • 2012-05-30
        相关资源
        最近更新 更多