ybenhssaien/authorization-bundle

Symfony 扩展,用于授权实体属性

v1.0 2020-07-13 07:07 UTC

This package is auto-updated.

Last update: 2024-09-20 17:58:46 UTC


README

AuthorizationBundle 用于管理实体属性的授权,这些属性可以是可读的、可写的或两者兼具,由某些角色而非其他角色,每个实体的属性都可以使用 PHP 文件中的 isGranted() 或 Twig 版本的 is_granted() 来授权或拒绝读取或写入。

安装

  1. 使用 composer 安装
    composer require ybenhssaien/authorization-bundle
  2. config/bundles.php 中启用它
    return [
       ......
       Ybenhssaien\AuthorizationBundle\AuthorizationBundle::class => ['all' => true],
    ];

示例

  • 属性声明
<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Ybenhssaien\AuthorizationBundle\Annotation\Authorization;
use Ybenhssaien\AuthorizationBundle\Annotation\HasAuthorizations;

/**
 * @ORM\Entity()
 *
 * @HasAuthorizations()
 */
class Person
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=10)
     *
     * @Authorization(
     *      "name" : "gender_renamed",
     *      {
     *          "ROLE_HR" : {"read": true, "write": true},
     *          "ROLE_USER" : {"read": true, "write": false},
     *          "ROLE_OTHERS" : {"read": true, "write": false},
     *      }
     *  )
     */
    private $gender;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @Authorization({
     *     "ROLE_HR",
     *     "ROLE_USER" : {"write": false},
     *     "ROLE_OTHERS" : {"write": false},
     * })
     */
    private $firstName;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @Authorization({
     *     "ROLE_HR",
     *     "ROLE_USER" : {"write": false},
     *     "ROLE_OTHERS" : {"write": false},
     * })
     */
    private $lastName;

    /**
     * @ORM\Column(type="string", length=10)
     *
     * @Authorization(
     *     {"ROLE_HR"},
     *     "aliases" : {"code"},
     * )
     */
    private $hrCode;
}
  • 在 FormBuilder 中的使用
<?php

namespace App\Form;

use App\Entity\Person;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security;

class PersonType extends AbstractType
{
    protected Security $security;

    public function __construct(Security $security)
    {
        $this->security = $security;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // "gender_renamed" is the name chosen for this property ("gender" doesn't exist)
        if ($this->security->isGranted('write', [Person::class, 'gender_renamed'])) {
            $builder->add('gender');
        }

        if ($this->security->isGranted('write', [Person::class, 'firstName'])) {
            $builder->add('firstName');
        }

        if ($this->security->isGranted('write', [Person::class, 'lastName'])) {
            $builder->add('lastName');
        }

        // "code" is declared an alias of "hrCode" (can use both of them)
        if ($this->security->isGranted('write', [Person::class, 'code'])) {
            $builder->add('hrCode');
        }
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Person::class,
        ]);
    }
}
  • 在 Twig 中的使用
{# Accepts "person" as object #}
{% if is_granted('read', [person, 'firstName']) %}
    {{ person.firstName }}
{% endif %}

{# Accepts class name #}
{% if is_granted('read', ['App\\Entitiy\\Person', 'lastName']) %}
    {{ person.lastName }}
{% endif %}

文档

  1. 注解

    • 必需 : 声明一个具有授权的实体,如果没有 @HasAuthorizations 注解,实体将被自动忽略。
    <?php
    
    namespace App\Entity;
    
    // ....   
    use Ybenhssaien\AuthorizationBundle\Annotation\HasAuthorizations;
    
    /**
     * @Entity()
     *
     * @HasAuthorizations()
     */
    class Entity
    {}       

    重要 : 授权仅适用于使用 Doctrine ORM 的实体

    • 使用 @Authorization() 声明属性上的授权映射,该注解接受 3 个命名参数
      • name : [可选] 字符串,用于替换默认的属性名称(不带 $,例如:private $propertyOfEntity => propertyOfEntity
         /**
           * @ORM\Column(type="string")
           *
           * @Authorization(
           *      "name" : "custom_name",
           *      {/* Roles */}
           *  )
           */
        private $property;
      • aliases : [可选] 用于目标属性的名称数组
         /**
           * @ORM\Column(type="string")
           *
           * @Authorization(
           *      "aliases" : {"alias1", "alias2", ....},
           *      {/* Roles */}
           *  )
           */
        private $property;
      • roles : [可选] 角色授权数组,每个角色可以有键为 read 和 write 的选项数组,其值为布尔值。
        • 接受没有 roles 键的角色作为参数是可以接受的
         /**
           * @ORM\Column(type="string")
           *
           * @Authorization(
           *      "roles" : {
           *        "ROLE_USER",
           *        "ROLE_GUEST" : {"write" : false},
           *        "ROLE_OTHER" : {"read" : false, "write" : false},
           *      }
           *  )
           */
        private $property;
      
         /**
           * @ORM\Column(type="string")
           *
           * @Authorization(
           *      "name" : "custom_name",
           *      "aliases" : {"alias"},
           *      {
           *        "ROLE_USER",
           *        "ROLE_GUEST" : {"write" : false},
           *        "ROLE_OTHER" : {"read" : false, "write" : false},
           *      }
           *  )
           */
        private $property2;
      • 未声明操作默认值为 true(例如,对于没有操作的 ROLE_USER,相当于 {"read" : true, "write" : true}
      • 不声明 @Authorization,等同于 {"read" : false, "write" : false}(对于未声明的角色也是同样情况)
  2. 检查授权

要检查属性的授权,请使用 Security 的 isGranted() 方法或 Twig 的等价方法 is_granted(),其签名如下

  • isGranted($action, [$entity, $property] :
    • $action : 'read' 或 'write' 字符串
    • $entity : 对象或作为字符串的类名
    • $property : 属性名称,自定义 name 或已声明的 alias

命令

  • bin/console debug:authorization : 显示授权映射

授权服务

  • AuthorizationService : 包含检查授权和获取授权映射的方法。
    • getAuthorizationMap(): AuthorizationMap : 返回一个包含授权映射和映射实体的 AuthorizationMap 实例。
    • canReadData(string $property, string $entity): bool : 检查属性是否授权读取。
    • canWriteData(string $property, string $entity): bool : 检查属性是否授权写入。
    • isPropertyExists(string $property, string $entity): bool : 检查属性是否已声明授权。
  • AuthorizationMap : 包含声明的授权映射和实体。
    • getMap(): array : 返回授权映射。
    • getEntities(): array : 返回支持的实体列表。

贡献 & 报告错误

@由 Youssef BENHSSAIEN 开发