admin-platform/rbac-bundle
Symfony2 Role-Based Access Control (RBAC) bundle powered by the Sylius RBAC component. Integrate roles and permissions into your app, with phpspec examples for testing and an MIT license.
Installation
composer require admin-platform/rbac-bundle
Add to config/bundles.php:
return [
// ...
AdminPlatform\RbacBundle\AdminPlatformRbacBundle::class => ['all' => true],
];
Database Migration Run migrations to create RBAC tables:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
First Use Case: Assigning a Role
use AdminPlatform\RbacBundle\Entity\Role;
use AdminPlatform\RbacBundle\Entity\User;
$role = $roleRepository->findOneBy(['name' => 'ROLE_ADMIN']);
$user = $userRepository->find(1);
$user->addRole($role);
$entityManager->flush();
Check Permissions in Controller
use Symfony\Component\HttpFoundation\Response;
use AdminPlatform\RbacBundle\Security\Authorization\Voter\RoleVoter;
public function secureAction(RoleVoter $voter, UserInterface $user): Response
{
if (!$voter->vote($user, 'EDIT', $this->getParameter('some_entity'))) {
throw $this->createAccessDeniedException();
}
// ...
}
config/packages/admin_platform_rbac.yaml):
admin_platform_rbac:
hierarchy:
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_USER]
ROLE_ADMIN: [ROLE_USER]
$role = $roleRepository->findOneBy(['name' => 'ROLE_EDITOR']);
$user->addRole($role); // Automatically inherits ROLE_USER if defined in hierarchy
namespace App\Security\Voter;
use AdminPlatform\RbacBundle\Security\Authorization\Voter\AbstractVoter;
class ProductVoter extends AbstractVoter
{
protected function supports($attribute, $subject): bool
{
return in_array($attribute, ['EDIT', 'DELETE']) && $subject instanceof Product;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
return $user->hasRole('ROLE_PRODUCT_MANAGER');
}
}
Register in security.yaml:
security:
access_control:
- { path: ^/admin/product, roles: ROLE_PRODUCT_MANAGER }
User Onboarding:
ROLE_USER) via POST_PERSIST event listener.$user->addRole($roleRepository->findOneBy(['name' => 'ROLE_USER']));
$entityManager->flush();
Bulk Role Updates:
$query = $entityManager->createQuery('SELECT u FROM App\Entity\User u WHERE u.isActive = true');
$users = $query->getResult();
foreach ($users as $user) {
$user->addRole($roleRepository->findOneBy(['name' => 'ROLE_ACTIVE_USER']));
}
$entityManager->flush();
API Integration:
Symfony\Bundle\FrameworkBundle\Controller\AbstractController to inject RoleVoter:
public function apiAction(RoleVoter $voter, UserInterface $user): JsonResponse
{
if (!$voter->vote($user, 'VIEW', $resource)) {
return $this->json(['error' => 'Unauthorized'], 403);
}
return $this->json($resource);
}
Circular Dependencies in Role Hierarchy:
post_load lifecycle callback:
public function postLoad(LifecycleEventArgs $args)
{
$role = $args->getObject();
$this->validateHierarchy($role);
}
Symfony\Component\Validator\Constraints\Valid with a custom constraint.Permission Caching:
php bin/console cache:clear
$this->container->get('security.token_storage')->setToken(new AnonymousToken());
Symfony 5.4+ Compatibility:
security.yaml to avoid deprecation warnings:
security:
access_control:
- { path: ^/, roles: PUBLIC_ACCESS }
- { path: ^/admin, roles: ROLE_ADMIN }
dump($user->getRoles()); // Returns array of Role objects
config/packages/dev/admin_platform_rbac.yaml:
admin_platform_rbac:
debug: true
Logs will show role inheritance and permission checks.Custom Role Storage:
AdminPlatform\RbacBundle\Repository\RoleRepositoryInterface for non-DB storage (e.g., Redis).Dynamic Role Loading:
AdminPlatform\RbacBundle\Security\Authorization\Voter\RoleVoter to load roles from external APIs.Event Listeners:
admin_platform_rbac.role.pre_persist to validate roles before save:
$event->setRole($event->getRole()->setName(strtoupper($event->getRole()->getName())));
admin_platform_rbac.hierarchy to override defaults at runtime:
$container->getParameter('admin_platform_rbac.hierarchy')['ROLE_CUSTOM'] = ['ROLE_USER'];
User entity extends AdminPlatform\RbacBundle\Entity\UserInterface:
use AdminPlatform\RbacBundle\Entity\UserInterface;
class AppUser implements UserInterface { ... }
$role = $roleRepository->findOneBy(['name' => 'ROLE_USER']);
$users = $userRepository->findBy(['active' => true]);
foreach ($users as $user) {
$user->addRole($role);
}
$entityManager->flush(); // Single flush for all users
roles field to User entity for faster access:
#[ORM\Column(type: 'json')]
private array $rolesJson = [];
How can I help you explore Laravel packages today?