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


Understanding user permissions and how to apply it

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

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

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

看看其他模块,我意识到当你创建一些东西时,它们会让用户手动设置权限。

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

$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));

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

因此,如果用户选择"Everyone",每个人都应该能够删除和编辑该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;
}

在同一个操作中还有其他几个位,我不明白他们在做什么,下面是来自轮询控制器中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%诚实。以上任何一项是否可以为我清除,帮助向我解释,如果可能的话,我如何将我想要的权限应用到我的模块。

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

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

  • application/modules/Authentication/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/Authentication/Controller/Action/Helper/RequireAuth.php
  • application/modules/Core/Controller/Action/Helper/RequireSubject.php
  • application/modules/Core/Controller/Action/Helper/RequireUser.php

在Album_AlbumController类中可以找到如何使用这些助手的一个很好的示例:应用程序/模块/Album/controller/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帮助程序不那么直接。为了简洁起见,我将省略大部分抽象的内部工作。最后,助手指向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_authentication_permissions表查询数据库。

  1. engine4_authorization_levels表包含成员级别由SocialEngine开箱即用创建,以及自定义成员从管理员中的"管理">"成员级别"部分创建的级别面板
  2. engine4_authorization_permissions表包含所有默认和管理员指定的权限处理,例如成员级别设置
  3. engine4_authorization_allow包含单个对象的权限数据。例如信息关于谁能够查看相册的信息会放在那里。engine4_authorization_allow.role_id(是否映射到项模型的id)被允许访问engine4_authorization_allow.resource_id(映射到型号)由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)被忽略为不允许。它们期望一些自定义逻辑,以便适当地处理授权。

我也不熟悉SocialEngine,但经常使用Zend Framework。我会尽力给你一些提示,希望其他人能在需要的时候给你更多的提示。

看起来SE在您刚才展示的大部分代码中都使用了Zend_Auth和Zend_Acl。

理解Zend_Auth是有帮助的,但所有这部分都已经完成,超出了你想做的大部分。Zend_Acl是你可能会花很多时间阅读的内容。

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

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

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

接下来,他们似乎正在调用一个名为requireAuth的操作助手,该助手可以设置auth参数或检查用户是否有访问权限。这是建立在ZF上的Social Engine的一部分,不是ZF特定的,因此您可能需要阅读更多关于该助手如何工作的文档。

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

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

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

希望对一些人有所帮助。