Symfony 2 ACL и иерархия ролей

Я немного застрял и не смог найти ответ на этот вопрос.

В моем тесте приложения я создал два пользователя и комментарий для пользователей, которые правильно отображаются.

Я создал небольшой контроллер, который в зависимости от пользователя добавит комментарий и данные в таблицы ACL , если я создам свой комментарий в качестве стандартного пользователя с соответствующим для «ROLE_USER» и попытаюсь получить к нему доступ как пользователь с role 'ROLE_ADMIN' Я получаю доступ запрещен, он, кажется, полностью игнорирует иерархию security.yml.

Я знаю, что это работает, добавив вместо userid ROLE_USER и т. Д., Но я не хочу этого делать.

Ниже приведены примеры моего кода.

CommentController

<?php namespace ACL\TestBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Symfony\Component\HttpFoundation\Request; use ACL\TestBundle\Forms\Type\commentType; use ACL\TestBundle\Entity\Comment; use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Acl\Domain\ObjectIdentity; use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity; use Symfony\Component\Security\Acl\Permission\MaskBuilder; class DefaultController extends Controller { /** * @Route("/", name="_default") * @Template() */ public function indexAction() { die('success'); } /** * @Route("/comment/new/") * @Template() */ public function newAction(Request $request) { $comment = new Comment(); $form = $this->createForm(new commentType(), $comment); $form->handleRequest($request); if ($form->isValid()) { $comment->setUsers($this->getUser()); $em = $this->getDoctrine()->getManager(); $em->persist($comment); $em->flush(); // creating the ACL $aclProvider = $this->get('security.acl.provider'); $objectIdentity = ObjectIdentity::fromDomainObject($comment); $acl = $aclProvider->createAcl($objectIdentity); // retrieving the security identity of the currently logged-in user $securityIdentity = UserSecurityIdentity::fromAccount($this->getUser()); // grant owner access $acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER); $aclProvider->updateAcl($acl); } return array( 'form' => $form->createView(), ); } /** * @Route("/comment/{id}/", requirements={"id":"\d+"}) * @Template() */ public function editAction(Request $request,$id) { $em = $this->getDoctrine()->getManager(); $comment = $em->find('ACLTestBundle:Comment', $id); $securityContext = $this->get('security.context'); // check for edit access if (false === $securityContext->isGranted('EDIT',$comment)) { throw new AccessDeniedException(); } $form = $this->createForm(new commentType(), $comment); $form->handleRequest($request); if($form->isValid()){ $em->persist($comment); $em->flush(); } return array('form' => $form->createView()); } } 

security.yml

  security: encoders: ACL\TestBundle\Entity\User: plaintext acl: connection: default providers: database: entity: { class: ACLTestBundle:User } role_hierarchy: ROLE_ADMIN: [ROLE_USER, ROLE_ALLOWED_TO_SWITCH] firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: pattern: ^/ provider: database anonymous: true logout: true switch_user: true form_login: login_path: _security_login access_control: - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/, roles: IS_AUTHENTICATED_FULLY } 

Я ценю любой совет!

Проблема в том, что вы добавляете добавление базы ACL в UserIdentity и хотите проверить базу gran на RoleIdentity. Если вы хотите сделать это, измените базовую базу, создав ACL, как показано ниже.

 // creating the ACL $aclProvider = $this->get('security.acl.provider'); $objectIdentity = ObjectIdentity::fromDomainObject($comment); $acl = $aclProvider->createAcl($objectIdentity); // retrieving the security identity of the currently logged-in user $securityIdentity = UserSecurityIdentity::fromAccount($this->getUser()); // grant owner access $acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER); // grant EDIT access to ROLE_ADMIN $securityIdentity = new RoleSecurityIdentity('ROLE_ADMIN'); $acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_EDIT); $aclProvider->updateAcl($acl); 

Как вы видите, я сохранил доступ владельца к конкретному пользователю, а затем добавил доступ для редактирования для ROLE_ADMIN. Вы можете держать контроллер как есть.

Если вы не хотите создавать базу ролей, а просто хотите предоставить исключение для пользователей admin, вы можете изменить свой контроллер как

 // check for edit access if (false === $securityContext->isGranted('EDIT',$comment) && false === $securityContext->isGranted('ROLE_ADMIN') ) { throw new AccessDeniedException(); }