了解用户权限以及如何应用它

时间:2012-07-17 10:19:10

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

我正在使用使用Zend Framework的Social Engine为网站开发模块。我是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等。

所以扫描轮询控制器我发现这是在控制器的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的随机片段:

$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%诚实。可以为我清除以上任何内容,帮助向我解释一下,如果可能的话,我如何将我想要的权限应用到我的模块中。

2 个答案:

答案 0 :(得分:7)

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

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

  • 应用/模块/授权/控制器/动作/助手/ RequireAuth.php
  • 应用/模块/核心/控制器/动作/助手/ RequireAbstract.php
  • 应用/模块/核心/控制器/动作/助手/ RequireAdmin.php
  • 应用/模块/核心/控制器/动作/助手/ RequireSubject.php
  • 应用/模块/核心/控制器/动作/助手/ RequireUser.php

在大多数情况下,您唯一关注的是:

  • 应用/模块/授权/控制器/动作/助手/ RequireAuth.php
  • 应用/模块/核心/控制器/动作/助手/ RequireSubject.php
  • 应用/模块/核心/控制器/动作/助手/ 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检查查看者是否是登录用户
  3. requireAuth助手稍微不那么直截了当。为简洁起见,我将省略大部分抽象的内部工作。最后,帮助程序指向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中称为Models,预计位于模块的Models目录中。当调用isAllowed函数时,授权api将根据engine4_authorization_allow,engine4_authorization_levels和engine4_authorization_permissions表查询数据库。

    1. engine4_authorization_levels表包含成员级别 由SocialEngine开箱即用,以及自定义成员 从Manage>创建的级别管理员中的“成员级别”部分 面板。
    2. engine4_authorization_permissions表包含所有内容 默认和管理员指定的权限处理,例如成员 级别设置。
    3. engine4_authorization_allow包含 单个对象的权限数据。例如信息 关于谁能够查看相册将被放置在那里。 是否engine4_authorization_allow.role_id(映射到项目 允许模型的id访问 engine4_authorization_allow.resource_id(映射到项目ID为 model)由engine4_authorization_allow.value列确定 其中应包含数字0-5。
    4. 应用/模块/授权/原料药/ 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)不允许访问链接的资源。这与allow table

      中不存在的行相同

      1)允许访问链接资源

      2)允许访问和调节资源(即Superadmin,Admin和主持人级别)

      3-5)因不允许而被忽略。这些期望一些自定义逻辑,以便适当地处理授权。

答案 1 :(得分: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来自数据库。他们可以用它来判断一个人是否登录。

接下来,他们似乎正在调用名为requireAuth的{​​{3}},它可以设置auth params或检查用户是否有权访问。这是基于ZF构建的社交引擎的一部分,并不是特定于ZF的,因此您可能需要阅读有关该帮助程序如何工作的文档。

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

这个插件可能做的是创建一些新资源,可能是view,然后控制用户可以editZend_Acl某个特定民意调查。

如果您阅读了{{1}},那么更多的代码应该变得清晰。然后,您所要做的就是弄清楚插件如何存储角色和资源。我猜测有一种标准的方法可以将它存储在Social Engine中,并且ACL规则会在给定用户的每个请求时自动设置。

希望有所帮助。