olivier127/rbac-bundle

Symfony PhpRabcBundle 允许在 symfony 项目中使用 RBAC 控制访问

安装次数: 3,829

依赖项: 0

建议者: 0

安全: 0

星标: 18

关注者: 2

分支: 10

开放问题: 1

类型:symfony-bundle

v1.0.0 2024-09-12 07:34 UTC

This package is auto-updated.

Last update: 2024-09-13 09:31:00 UTC


README

PhpRBACBundle 是一个 symfony 7 扩展包,它提供了一个完整的访问控制库,用于 PHP。它为 PHP 开发者提供了一个易于使用的库,以实现 NIST Level 2 标准分层基于角色的访问控制。它是 OWASP 为 symfony 6 制作的 phprbac.net 库的重构。

目录

如何工作?

访问 https://phprbac.net/ :) 了解权限和角色的表示以及它们之间的交互。

Roles and Permissions

系统分层 RBAC 模型:蓝色:角色,灰色:用户,黄色:权限

安装

只需使用 composer 包管理器安装该软件包

composer require olivier127/rbac-bundle

在 config/bundles.php 中注册该扩展包

return [
    ...
    PhpRbacBundle\PhpRbacBundle::class => ['all' => true],
];

在 User 实体类中添加 PhpRbacBundle\Entity\UserRoleTrait 以添加 rbac 角色关系。

使用 doctrine 迁移或 doctrine 模式更新更新数据库模式以创建所有表

配置

准备 symfony

在防火墙安全配置部分的“需要预先认证的不同部分”中指定。

访问控制仅适用于网站的已认证部分。因此,我们将对所有用户使用基本的 ROLE_USER。ROLE_ADMIN 可以用于主要管理员,但他的权利将仅通过与其角色树中的 '/' 角色关联来分配。

示例

# config/packages/security.yaml
security:
    # ...

    role_hierarchy:
        ROLE_ADMIN: ROLE_USER

    access_control:
        - { path: ^/backend, roles: ROLE_USER }
        - { path: ^/todolist, roles: ROLE_USER }

添加 PhpRbac 配置

您必须创建自己的实体来驱动权限和角色。

示例

/* src/Entity/Role.php */
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use PhpRbacBundle\Entity\Role as EntityRole;
use PhpRbacBundle\Repository\RoleRepository;

#[ORM\Entity(repositoryClass: RoleRepository::class)]
#[ORM\Table('my_roles')]
class Role extends EntityRole
{

}
/* src/Entity/Permission.php */
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use PhpRbacBundle\Entity\Permission as EntityPermission;
use PhpRbacBundle\Repository\PermissionRepository;

#[ORM\Entity(repositoryClass: PermissionRepository::class)]
#[ORM\Table('my_permissions')]
class Permission extends EntityPermission
{

}

添加 php_rbac.yaml 以将实体关联到 rbac 核心

# config/packages/php_rbac.yaml
php_rbac:
  no_authentication_section:
    default: deny
  resolve_target_entities:
    user: App\Entity\User
    role: App\Entity\Role
    permission: App\Entity\Permission

创建角色和权限

使用 RoleManager 和 PermissionManager 添加所有所需的角色和权限

示例

向根添加权限

/** @var PhpRbacBundle\Core\PermissionManager $manager */
$manager = $this->container->get(PermissionManager::class);
$permission = $manager->add("notepad", "Notepad", PermissionManager::ROOT_ID);

添加链或权限

/** @var PhpRbacBundle\Core\PermissionManager $manager */
$manager = $this->container->get(PermissionManager::class);
$manager->addPath("/notepad/todolist/read", ['notepad' => 'Notepad', 'todolist' => "Todo list", "read" => "Read Access"]);

建立 rbac 关系

添加角色的方法相同

例如,我使用了链角色 "/editor/reviewer"。审阅者是编辑的子角色,编辑是根 "/" 的子角色。

/** @var PhpRbacBundle\Core\RoleManager $manager */
$manager = $this->container->get(RoleManager::class);
$manager->addPath("/editor/reviewer", ['editor' => 'Editor', 'reviewer' => "Reviewer"]);

将权限分配给角色

/** @var PhpRbacBundle\Core\RoleManager $manager */
$manager = $this->container->get(RoleManager::class);
$editorId = $manager->getPathId("/editor");
$editor = $manager->getNode($editorId);
$reviewerId = $manager->getPathId("/editor/reviewer");
$reviewer = $manager->getNode($reviewerId);

$manager->assignPermission($editor, "/notepad");
$manager->assignPermission($reviewer, "/notepad/todolist/read");
$manager->assignPermission($reviewer, "/notepad/todolist/write");

编辑角色将拥有 /notepad 权限及其所有子权限,而审阅者角色将仅拥有 /notepad/todolist/read/notepad/todolist/write 权限

分配角色给用户并检查权限

如果 UserRoleTraitUser 类中,您将拥有 addRbacRole。只需将角色添加到该实体中即可

/** @var PhpRbacBundle\Core\RoleManager $manager */
$manager = $this->container->get(RoleManager::class);
$editorId = $manager->getPathId("/editor");
$editor = $manager->getNode($editorId);

$user = $userRepository->find($userId);
$user->addRbacRole($user);
$userRepository->add($user, true);

要测试用户的权限或角色,请使用 PhpRbacBundle\Core\Rbac 类。

$rbacCtrl = $this->container->get(Rbac::class);
$rbacCtrl->hasPermission('/notepad', $userId);
$rbacCtrl->hasRole('/editor/reviewer', $userId);

控制器 RBAC

只需添加具有“已授权”属性的属性,如下例所示。属性 IsGrantedHasRole 会根据当前用户检查安全性。

namespace App\Controller;

...
use PhpRbacBundle\Attribute\AccessControl as RBAC;

#[Route('/todolist')]
#[RBAC\IsGranted('/notepad/todolist/read')]
class TodolistController extends AbstractController
{
    #[RBAC\IsGranted('/notepad/todolist/read')]
    #[Route('/', name: 'app_todolist_index', methods: ['GET'])]
    public function index(TodolistRepository $todolistRepository): Response
    {
        ...
    }

    #[RBAC\IsGranted('/notepad/todolist/write')]
    #[Route('/new', name: 'app_todolist_new', methods: ['GET', 'POST'])]
    public function new(Request $request, TodolistRepository $todolistRepository): Response
    {
        ...
    }

    #[RBAC\IsGranted('/notepad/todolist/read')]
    #[Route('/{id}', name: 'app_todolist_show', methods: ['GET'])]
    public function show(Todolist $todolist): Response
    {
        ...
    }

    #[RBAC\IsGranted('/notepad/todolist/write')]
    #[Route('/{id}/edit', name: 'app_todolist_edit', methods: ['GET', 'POST'])]
    public function edit(Request $request, Todolist $todolist, TodolistRepository $todolistRepository): Response
    {
        ...
    }

    #[RBAC\IsGranted('/notepad/todolist')]
    #[Route('/{id}', name: 'app_todolist_delete', methods: ['POST'])]
    public function delete(Request $request, Todolist $todolist, TodolistRepository $todolistRepository): Response
    {
        ...
    }
}

类上的第一个 RBAC\IsGranted 检查当前用户访问控制器的最低权限。每个动作上的 RBAC\IsGranted 检查执行动作所需的最小权限。

在示例中

  • /notepad/todolist/read 权限允许访问所有控制器以及 index 和 show 动作。
  • /notepad/todolist/write 权限允许编辑待办事项列表。
  • 作为读和写权限父级的 /notepad/todolist 权限允许删除。

/notepad/todolist 权限还具有读和写权限。

基于投票的RBAC

使用RbacVoter,您可以使用symfony安全系统来检查用户的RBAC权限(而非角色)。

示例

    #[IsGranted('/todolist/index', statusCode: 403, message: 'Access denied for user')]
    #[Route('/', name: 'app_todo_list_index', methods: ['GET'])]
    public function index(TodoListRepository $todoListRepository): Response

您需要将安全访问控制设置为一致(所有投票者都必须同意)。

将以下行添加到 config/packages/security.yaml

security:
    ...
    access_decision_manager:
        strategy: unanimous
        allow_if_all_abstain: false

Symfony CLI 命令

安装命令设置根节点角色和权限,并将它们关联起来。

  security:rbac:install

将权限添加到RBAC权限树中

security:rbac:permission:add

将权限添加到RBAC角色树中

security:rbac:role:add

将权限分配给一个角色

security:rbac:role:assign-permission

将角色分配给一个用户

security:rbac:user:assign-role

这些命令是交互式的。

Twig

测试用户是否拥有某个角色

{% if hasRole('/the/role') %}
...
{% endif %}

测试用户是否拥有某个权限

{% if hasPermission('/the/permission') %}
...
{% endif %}