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

7

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

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

我的RBAC实现如下: 用户->角色->权限 因此,每个用户(例如userA)可以拥有多个角色(例如reader,editor,admin),每个角色可以拥有多个权限(读取、更新、删除等)。

MySQL表格

  • users(用户列表)
  • roles(角色列表)
  • permissions(权限列表)
  • roles_permissions(角色-权限连接列表。例如editor->update)
  • users_roles(用户-角色连接列表。例如userA->editor)

现在我的问题是 我应该如何在MVC中实现这个?是否应该为:用户、角色、权限、角色_权限、用户_角色创建单独的模型,然后再创建一个authManager类?这种方式正确吗?是否有更好、更优雅的方式?

4个回答

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

2
您通常需要使用ACL库/类来管理ACL,因为您正在描述ACL。我不知道Kohana,但是通过快速搜索,我找到了这个Kohana ACL库。 https://github.com/synapsestudios/kohana-acl 但基本上,您确实需要模型来管理ACL库中的各个实体,例如用户、角色和权限。然后,在控制器或其他库中与ACL-API交互,以确定对应用程序的特定部分的访问权限。

1
我知道这个问题已经过去了,但是一个新项目出现了:
PHP-RBAC 是一个 PHP 分层 NIST 2 级标准的基于角色的访问控制,并且非常成熟。它还是一个 OWASP 项目。
我希望你会喜欢 http://phprbac.net 在 jframework 中,它被用于以 MVC 模式中合并 RBAC 的标准方式。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接