programarivm / easy-acl-bundle
在Symfony 5中使用的易于使用的访问控制列表(ACL)包。
0.9.07
2023-08-08 13:39 UTC
Requires
- php: >=7.1
- symfony/config: ^5.0
- symfony/dependency-injection: ^5.0
- symfony/http-kernel: ^5.0
This package is not auto-updated.
Last update: 2024-09-23 18:43:14 UTC
README
在Symfony 5中使用的易于使用的访问控制列表(ACL)包。
安装
通过composer
$ composer require programarivm/easy-acl-bundle
配置
在config/routes.yaml
中配置您的应用程序路由。
# config/routes.yaml api_post_create: path: /api/posts controller: App\Controller\Post\CreateController::index methods: POST api_post_delete: path: /api/posts/{id} controller: App\Controller\Post\DeleteController::index methods: DELETE api_post_edit: path: /api/posts/{id} controller: App\Controller\Post\EditController::index methods: PUT
设置权限,如下所示。
# config/packages/programarivm_easy_acl.yaml programarivm_easy_acl: target: App\Entity\User permission: - role: Superadmin routes: - api_post_create - api_post_delete - api_post_edit - role: Admin routes: - api_post_create - api_post_edit - role: Basic routes: - api_post_create
更新您的config/services.yaml
文件。
# config/services.yaml services: Programarivm\EasyAclBundle\Command\SetupCommand: arguments: $projectDir: '%kernel.project_dir%' tags: ['console.command'] Programarivm\EasyAclBundle\Repository\: resource: '../vendor/programarivm/easy-acl-bundle/src/Repository' autowire: true tags: ['doctrine.repository_service'] Programarivm\EasyAclBundle\EventListener\IdentitySubscriber: tags: ['doctrine.event_subscriber']
别忘了更新您的数据库模式
php bin/console doctrine:schema:update --force
这将在您的数据库中创建四个空表
easy_acl_identity
easy_acl_permission
easy_acl_role
easy_acl_route
这些与实体密切相关
Programarivm\EasyAclBundle\Entity\Identity
Programarivm\EasyAclBundle\Entity\Permission
Programarivm\EasyAclBundle\Entity\Role
Programarivm\EasyAclBundle\Entity\Route
以及存储库
Programarivm\EasyAclBundle\Repository\IdentityRepository
Programarivm\EasyAclBundle\Repository\PermissionRepository
Programarivm\EasyAclBundle\Repository\RoleRepository
Programarivm\EasyAclBundle\Repository\RouteRepository
easy-acl:setup
命令
命令行
php bin/console easy-acl:setup
This will reset the ACL. Are you sure to continue? (y) y
MySQL控制台
mysql> select * from easy_acl_identity;
Empty set (0.01 sec)
mysql> select * from easy_acl_permission;
+----+------------+-----------------+
| id | rolename | routename |
+----+------------+-----------------+
| 1 | Superadmin | api_post_create |
| 2 | Superadmin | api_post_delete |
| 3 | Superadmin | api_post_edit |
| 4 | Admin | api_post_create |
| 5 | Admin | api_post_edit |
| 6 | Basic | api_post_create |
+----+------------+-----------------+
6 rows in set (0.00 sec)
mysql> select * from easy_acl_role;
+----+------------+
| id | name |
+----+------------+
| 1 | Superadmin |
| 2 | Admin |
| 3 | Basic |
+----+------------+
3 rows in set (0.00 sec)
mysql> select * from easy_acl_route;
+----+-----------------+---------+-----------------+
| id | name | methods | path |
+----+-----------------+---------+-----------------+
| 1 | api_post_create | POST | /api/posts |
| 2 | api_post_delete | DELETE | /api/posts/{id} |
| 3 | api_post_edit | PUT | /api/posts/{id} |
+----+-----------------+---------+-----------------+
3 rows in set (0.00 sec)
如你所见,三个EasyAcl
表被填充了在config/packages/programarivm_easy_acl.yaml
中包含的数据,但是定义您的用户的身份取决于你。
如何将Superadmin
身份设置为alice
的示例
use Programarivm\EasyAclBundle\Entity\Identity; ... $user = self::$em->getRepository('App:User')->findOneBy(['username' => 'alice'); $role = self::$em->getRepository('EasyAclBundle:Role')->findOneBy(['name' => 'Superadmin']); $this->em->persist( (new Identity()) ->setUser($user) ->setRole($role) ); ... $this->em->flush();
mysql> select * from easy_acl_identity;
+----+---------+---------+
| id | role_id | user_id |
+----+---------+---------+
| 1 | 1 | 1 |
+----+---------+---------+
1 row in set (0.00 sec)
最后,权限存储库可以帮助你确定特定角色是否可以访问给定的资源
$isAllowed = $this->em ->getRepository('EasyAclBundle:Permission') ->isAllowed('Superadmin', 'api_post_show');
更具体地说,下面的示例展示了如何在event subscriber
中使用权限存储库来授权JWT令牌。
// src/EventSubscriber/TokenSubscriber.php namespace App\EventSubscriber; use App\Controller\AccessTokenController; use Doctrine\ORM\EntityManagerInterface; use Firebase\JWT\JWT; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\ControllerEvent; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\KernelEvents; class TokenSubscriber implements EventSubscriberInterface { public function __construct(EntityManagerInterface $em) { $this->em = $em; } public function onKernelController(ControllerEvent $event) { $controller = $event->getController(); // when a controller class defines multiple action methods, the controller // is returned as [$controllerInstance, 'methodName'] if (is_array($controller)) { $controller = $controller[0]; } if ($controller instanceof AccessTokenController) { $jwt = substr($event->getRequest()->headers->get('Authorization'), 7); try { $decoded = JWT::decode($jwt, getenv('JWT_SECRET'), ['HS256']); } catch (\Exception $e) { throw new AccessDeniedHttpException('Whoops! Access denied.'); } $user = $this->em->getRepository('App:User') ->findOneBy(['id' => $decoded->sub]); $identity = $this->em->getRepository('EasyAclBundle:Identity') ->findBy(['user' => $user]); $rolename = $identity[0]->getRole()->getName(); $routename = $event->getRequest()->get('_route'); $isAllowed = $this->em->getRepository('EasyAclBundle:Permission') ->isAllowed($rolename, $routename); if (!$isAllowed) { throw new AccessDeniedHttpException('Whoops! Access denied.'); } } } public static function getSubscribedEvents() { return [ KernelEvents::CONTROLLER => 'onKernelController', ]; } }
EasyAcl
使用方法
该包为您提供了Programarivm\EasyAclBundle\EasyAcl
,您可以使用它以友好、面向对象的方式访问YAML配置文件中的包信息。
示例
// src/DataFixtures/EasyAcl/RoleFixtures.php namespace App\DataFixtures\EasyAcl; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface; use Doctrine\Common\Persistence\ObjectManager; use Programarivm\EasyAclBundle\EasyAcl; use Programarivm\EasyAclBundle\Entity\Role; class RoleFixtures extends Fixture implements FixtureGroupInterface { private $easyAcl; public function __construct(EasyAcl $easyAcl) { $this->easyAcl = $easyAcl; } public function load(ObjectManager $manager) { foreach ($this->easyAcl->getPermission() as $key => $permission) { $role = (new Role())->setName($permission['role']); $manager->persist($role); $this->addReference("role-$key", $role); } $manager->flush(); } public static function getGroups(): array { return [ 'easy-acl', ]; } }
示例
// src/DataFixtures/EasyAcl/IdentityFixtures.php namespace App\DataFixtures\EasyAcl; use App\DataFixtures\UserFixtures; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface; use Doctrine\Common\DataFixtures\DependentFixtureInterface; use Doctrine\Common\Persistence\ObjectManager; use Programarivm\EasyAclBundle\EasyAcl; use Programarivm\EasyAclBundle\Entity\Identity; class IdentityFixtures extends Fixture implements FixtureGroupInterface, DependentFixtureInterface { private $easyAcl; public function __construct(EasyAcl $easyAcl) { $this->easyAcl = $easyAcl; } public function load(ObjectManager $manager) { for ($i = 0; $i < UserFixtures::N; $i++) { $index = rand(0, count($this->easyAcl->getPermission())-1); $user = $this->getReference("user-$i"); $role = $this->getReference("role-$index"); $manager->persist( (new Identity()) ->setUser($user) ->setRole($role) ); } $manager->flush(); } public static function getGroups(): array { return [ 'easy-acl', ]; } public function getDependencies(): array { return [ RoleFixtures::class, UserFixtures::class, ]; } }
贡献
你能帮助使这个Symfony包变得更好吗?
- 请随意发送一个pull请求
- 发送电子邮件至info@programarivm.com,主题为"EasyAcl"
- 在Twitter上给我留言
谢谢。