基于角色的访问控制 - 正确的MVC模式

时间:2011-12-22 07:48:30

标签: php model-view-controller kohana rbac

半年前我开始使用MVC模式,我仍然有一些误解。

现在我想在我的应用程序中实现基于角色的访问控制。但是,我的问题不是关于RBAC,而是关于MVC。

我对RBAC的实施是这样的: 用户>角色的>权限 所以每个用户(例如userA)都可以拥有多个角色(例如读者,编辑者,管理员),每个角色都可以拥有许多权限(读取,更新,删除等)。

MySQL表格

  • 用户(用户列表)
  • 角色(角色列表)
  • 权限(权限列表)
  • roles_permissions(角色列表 - >权限连接。例如编辑 - >更新)
  • users_roles(用户列表 - >角色连接。例如用户A->编辑器)

现在我的问题是 我应该如何在MVC中实现它? 有一个单独的模型:用户,角色,权限,roles_permissions,users_roles,而不是具有创建用户,角色,权限,roles_permissions和user_roles的authManager类? 这种方式是否正确?是否有更好的,可能更优雅的方式?

4 个答案:

答案 0 :(得分:8)

基本上我会坚持使用许多现有的Kohana ACL库中的一个,而不是自己编写(或者至少尝试一下它们是否符合您的需求)。

您可能想要检查此线程(Wouter A1,A2和ACL模块) - http://forum.kohanaframework.org/discussion/1988/releases-a1-authentication-acl-acl-for-kohana-a2-object-level-authorization/p1
它不断更新和维护,也可用于3.2版本。

如果您认为Wouter模块很复杂,您还可以检查Vendo ACL模块,这非常简单,并消除了很多复杂问题 - https://github.com/vendo/acl
示例如何使用它 - http://forum.kohanaframework.org/discussion/9517/getting-started-with-vendo-acl/p1

答案 1 :(得分:2)

您通常希望为此使用ACL库/类,因为它是您正在描述的ACL。我不知道Kohana但是从快速谷歌我发现了这个Kohana ACL库。 https://github.com/synapsestudios/kohana-acl

但基本上你确实需要模型来管理ACL库中的单独实体,如用户,角色和权限。然后与控制器或其他库中的ACL-api交谈,以确定对应用程序特定部分的访问权限。

答案 2 :(得分:1)

我正在复制/粘贴KohanaPHP主应用程序控制器的代码,假设我们已经包含了Zend_ACL。

请注意我有基于用户的权限,而不是基于群组的权限...虽然这可以轻松编辑。

<?php

defined('SYSPATH') OR exit('No direct script access.');

class Controller_Application extends Controller_Template
{

    protected static $acl;
    public $template = 'default';

    public function before()
    {
        parent::before();
        session_start();
        self::$acl = new Zend_Acl();
        $this->set_permissions($_SESSION['userid']);
    }

    protected function check_access($resource, $privilege, $redirect = TRUE)
    {
        $permission = (self::$acl->has($resource) AND self::$acl->isAllowed($_SESSION['userid'], $resource, $privilege));
        if (!$permission AND $redirect)
            $this->request->redirect('user/denied');
        elseif (!$permission AND !$redirect)
            return FALSE;
        elseif ($permission AND !$redirect)
            return TRUE;
    }

    protected function set_permissions($user_id)
    {
        $result = DB::select()
            ->from('permissions')
            ->where('user_id', '=', $user_id)
            ->execute()
            ->as_array();
        self::$acl->addRole(new Zend_Acl_Role($user_id));
        foreach ($result AS $permission)
        {
            if (!self::$acl->has($permission['resource']))
                self::$acl->add(new Zend_Acl_Resource($permission['resource']));
            self::$acl->allow($user_id, $permission['resource'], $permission['privilege']);
        }
    }
}

?>

然后我检查控制器中的访问权限:$this->check_access('events', 'add');

答案 3 :(得分:1)

我知道这条路很冷,但是又出现了一个新项目:

PHP-RBAC是一个PHP分层NIST Level 2标准基于角色的访问控制,非常成熟。它也是一个OWASP项目。

我希望你在http://phprbac.net

享受它

它在jframework中的使用方式是将RBAC纳入MVC模式的标准方法。