【问题标题】:Understanding user permissions and how to apply it了解用户权限以及如何应用它
【发布时间】:2012-07-16 06:04:53
【问题描述】:

我正在使用Social Engine 为使用 Zend 框架的站点开发一个模块。我是 Zend Framework 和 Social Engine 的新手,但在 OOP 和 MVC 架构方面有经验,因此可以相对较快地掌握基础知识。

它是我正在开发的一个测试模块,所以刚刚构建了一个简单的模块,用户可以在其中创建、编辑或删除 CD 信息。然后有一个小部件可以显示在他们喜欢的地方,其中显示了 CD 信息。

我现在需要设置人们可以看到的 CD 的权限等。所以我研究了其他模块,发现 Poll 模块就是一个具体的例子。

查看其他模块,我意识到当您创建某些内容时,它们会让用户手动设置权限。

所以将此代码添加到我的表单中以创建具有相关权限的选择框:

$auth = Engine_Api::_()->authorization()->context;
$user = Engine_Api::_()->user()->getViewer();
$viewOptions = (array) Engine_Api::_()->authorization()->getAdapter('levels')->getAllowed('ryan', $user, 'auth_view');
$viewOptions = array_intersect_key($availableLabels, array_flip($viewOptions));

$privacy = null;

if( !empty($viewOptions) && count($viewOptions) >= 1 ) {
    // Make a hidden field
    if(count($viewOptions) == 1) {
        //$this->addElement('hidden', 'auth_view', array('value' => key($viewOptions)));
        $privacy  = new Zend_Form_Element_Hidden('auth_view');
        $privacy->setValue(key($viewOptions));
        // Make select box
    } else {
        $privacy = new Zend_Form_Element_Select('auth_view');
        $privacy->setLabel('Privacy')
                ->setDescription('Who may see this CD?')
                ->setMultiOptions($viewOptions)
                ->setValue(key($viewOptions));
        /*$this->addElement('Select', 'auth_view', array(
            'label' => 'Privacy',
            'description' => 'Who may see this CD?',
            'multiOptions' => $viewOptions,
            'value' => key($viewOptions),
        ));*/
    }
}

$this->addElements(array($artist, $title, $privacy, $submit));

老实说,除了明显地创建一个选择框并用指定的值填充它之外,我并不完全确定这段代码的作用。

因此,如果用户选择“所有人”,每个人都应该能够删除和编辑该 cd,等等。

显然我认为控制器必须有一些代码可以处理确定用户是否有权查看每个 cd 等。

所以扫描 Poll 控制器我发现这是在控制器的 init 函数中:

public function init() {
    // Get subject
    $poll = null;
    if( null !== ($pollIdentity = $this->_getParam('poll_id')) ) {
        $poll = Engine_Api::_()->getItem('poll', $pollIdentity);
        if( null !== $poll ) {
            Engine_Api::_()->core()->setSubject($poll);
        }
    }

    // Get viewer
    $this->view->viewer = $viewer = Engine_Api::_()->user()->getViewer();
    $this->view->viewer_id = Engine_Api::_()->user()->getViewer()->getIdentity();

    // only show polls if authorized
    $resource = ( $poll ? $poll : 'poll' );
    $viewer = ( $viewer && $viewer->getIdentity() ? $viewer : null );
    if( !$this->_helper->requireAuth()->setAuthParams($resource, $viewer, 'view')->isValid() ) {
        return;
    }
}

在顶部的每个操作中,它们都有一些不同的授权代码,一个这样的例子是editAction,它的顶部有这个代码:

// Check auth
if( !$this->_helper->requireUser()->isValid() ) {
    return;
}
if( !$this->_helper->requireSubject()->isValid() ) {
    return;
}
if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'edit')->isValid() ) {
    return;
}

在同一个动作中还有其他几个我不明白他们在做什么的位,下面是来自 Poll 控制器中 editAction 的随机 sn-ps:

$auth = Engine_Api::_()->authorization()->context;
$roles = array('owner', 'owner_member', 'owner_member_member', 'owner_network', 'registered', 'everyone');

// Populate form with current settings
$form->search->setValue($poll->search);
foreach( $roles as $role ) {
    if( 1 === $auth->isAllowed($poll, $role, 'view') ) {
        $form->auth_view->setValue($role);
    }
    if( 1 === $auth->isAllowed($poll, $role, 'comment') ) {
        $form->auth_comment->setValue($role);
    }
}

// CREATE AUTH STUFF HERE
if( empty($values['auth_view']) ) {
    $values['auth_view'] = array('everyone');
}
if( empty($values['auth_comment']) ) {
    $values['auth_comment'] = array('everyone');
}

$viewMax = array_search($values['auth_view'], $roles);
$commentMax = array_search($values['auth_comment'], $roles);

我的问题是,我真的不太了解上述任何一项,并且在坐了几天并在谷歌上搜索到我的手指受伤之后,我仍然不知道我是否 100% 诚实。可以为我清除以上任何内容,帮助向我解释事情,如果可能的话,我如何将我想要的权限应用于我的模块。

【问题讨论】:

    标签: php zend-framework permissions user-permissions socialengine


    【解决方案1】:

    我也不熟悉 SocialEngine,但经常使用 Zend Framework。我会尽量给你一些提示,如果需要的话,希望其他人可以为你补充更多。

    看起来 SE 在您刚刚展示的大部分代码中都使用了 Zend_AuthZend_Acl

    了解Zend_Auth 会有所帮助,但所有这部分都已完成,超出了您想要做的大部分工作。 Zend_Acl 是您可能会花费大量时间阅读的内容。

    理解Zend_AuthZend_Acl 之间区别的关键概念是Zend_Auth 对用户进行身份验证。也就是说,它根据某处的数据库检查提供的凭据,并说这个人就是他们所说的人,因为他们提供了正确的身份(例如,用户名和密码匹配)。另一方面,Zend_Acl 用于根据角色允许或拒绝对给定资源的访问。

    简单地说,Zend_Auth允许用户做什么无关,只是他们是他们所说的那个人。 Zend_Acl 表示用户有权或无权访问特定特性或功能(资源)。

    我没有查看他们的代码来确认这一点,但Engine_Api::_()->user()->getViewer()->getIdentity(); 似乎正在从数据库中提取用户的身份,乍一看似乎是null 或用户的id。他们可以使用它来判断一个人是否已登录。

    接下来,他们似乎正在调用一个名为 requireAuthaction helper,它可以设置身份验证参数或检查用户是否具有访问权限。这是基于 ZF 构建的 Social Engine 的一部分,不是 ZF 特定的,因此您可能需要阅读他们的文档以了解该助手的工作原理。

    我认为这个助手只是调用Zend_Acl::isValid() 来确定用户角色是否有权访问特定资源的一种间接方式。 Zend_Acl 工作非常简单。您可以根据role 尝试访问它们来授予或拒绝对某些resources 的访问。默认情况下,除非特别允许,否则拒绝访问所有资源。

    这个插件可能做的是创建一些新资源,可能是poll,然后控制用户可以viewedit 进行特定投票。

    如果您阅读了Zend_Acl,更多的代码应该会变得清晰。然后你所要做的就是弄清楚插件是如何存储角色和资源的。我猜有一种标准方法可以将其存储在社交引擎中,并且 ACL 规则会在给定用户的每个请求上自动设置。

    希望对一些人有所帮助。

    【讨论】:

      【解决方案2】:

      我将简要介绍如何使用授权,但是需要通过查看 SocialEngine 的代码来推断出更详细的信息。请注意,虽然我们不为 SocialEngine 编译文档,但我们的开发人员在我们的代码中使用了 PHPDocumentor 样式语法,您可以使用像 Neatbeans (http://netbeans.org/) 这样的 IDE 来快速访问该信息。

      SocialEngine 有一些控制器动作助手类,用于在动作控制器中进行查询授权:

      • application/modules/Authorization/Controller/Action/Helper/RequireAuth.php
      • application/modules/Core/Controller/Action/Helper/RequireAbstract.php
      • application/modules/Core/Controller/Action/Helper/RequireAdmin.php
      • application/modules/Core/Controller/Action/Helper/RequireSubject.php
      • application/modules/Core/Controller/Action/Helper/RequireUser.php

      在大多数情况下,您只关心这些:

      • application/modules/Authorization/Controller/Action/Helper/RequireAuth.php
      • application/modules/Core/Controller/Action/Helper/RequireSubject.php
      • application/modules/Core/Controller/Action/Helper/RequireUser.php

      可以在 Album_AlbumController 类中找到如何使用这些帮助器的一个很好的示例: 应用程序/模块/相册/控制器/AlbumController.php

      public function init()
      {
      if( !$this->_helper->requireAuth()->setAuthParams('album', null, 'view')->isValid() ) return;
      
      if( 0 !== ($photo_id = (int) $this->_getParam('photo_id')) &&
      null !== ($photo = Engine_Api::_()->getItem('album_photo', $photo_id)) )
      {
      Engine_Api::_()->core()->setSubject($photo);
      }
      
      else if( 0 !== ($album_id = (int) $this->_getParam('album_id')) &&
      null !== ($album = Engine_Api::_()->getItem('album', $album_id)) )
      {
      Engine_Api::_()->core()->setSubject($album);
      }
      }
      
      public function editAction()
      {
      if( !$this->_helper->requireUser()->isValid() ) return;
      if( !$this->_helper->requireSubject('album')->isValid() ) return;
      if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'edit')->isValid() ) return;
      

      init 函数中的代码简单地设置访问页面的要求,然后在 editAction 函数中对授权数据进行检查。 requireSubject 和 requireUser 助手非常简单:

      1. requireSubject 期望页面的主题设置在 上面的例子是在 init 函数中完成的
      2. requireUser 检查查看者是否为登录用户

      requireAuth 帮助器不太直接。为简洁起见,我将省略大部分抽象的内部工作。最后,helper 指向 Authorization_Api_Core::isAllowed 函数: 应用程序/模块/授权/核心/Api.php

      /**
      * Gets the specified permission for the context
      *
      * @param Core_Model_Item_Abstract|string $resource The resource type or object that is being accessed
      * @param Core_Model_Item_Abstract $role The item (user) performing the action
      * @param string $action The name of the action being performed
      * @return mixed 0/1 for allowed, or data for settings
      */
      public function isAllowed($resource, $role, $action = 'view')
      

      函数期望的 $resource 和 $role 对象是 Zend_Db_Table_Row 的实例,在 SocialEngine 中被称为模型,并且期望位于模块的模型目录中。当isAllowed函数被调用时,授权api会根据engine4_authorization_allow、engine4_authorization_levels和engine4_authorization_permissions表查询数据库。

      1. engine4_authorization_levels 表包含成员级别 由 SocialEngine 开箱即用创建,以及自定义成员 从管理员的“管理”>“成员级别”部分创建的级别 面板。
      2. engine4_authorization_permissions 表包含所有 default和admin指定的权限处理,比如member 水平设置。
      3. engine4_authorization_allow 包含 单个对象的权限数据。例如信息 关于谁能够查看相册的信息将被放置在那里。 是否为 engine4_authorization_allow.role_id(映射到项目 模型的 id) 被允许访问 engine4_authorization_allow.resource_id(映射到项目 id model) 由 engine4_authorization_allow.value 列确定 其中应包含一个数字 0-5。

      应用程序/模块/授权/Api/Core.php

      class Authorization_Api_Core extends Core_Api_Abstract
      {
      /**
      * Constants
      */
      const LEVEL_DISALLOW = 0;
      const LEVEL_ALLOW = 1;
      const LEVEL_MODERATE = 2;
      const LEVEL_NONBOOLEAN = 3;
      const LEVEL_IGNORE = 4;
      const LEVEL_SERIALIZED = 5;
      

      0) 不允许访问链接的资源。这与允许表中不存在的行相同

      1) 也允许访问链接的资源

      2) 允许访问和管理资源(即超级管理员、管理员和版主级别)

      3-5) 被忽略为不允许。这些需要一些自定义逻辑以便适当地处理授权。

      【讨论】:

        猜你喜欢
        • 2018-12-03
        • 2012-08-21
        • 1970-01-01
        • 1970-01-01
        • 2012-03-22
        • 1970-01-01
        • 1970-01-01
        • 2013-04-05
        • 2019-12-03
        相关资源
        最近更新 更多