php – 在没有SonataUserBundle的Sonata中删除每个用户角色的特定路由

前端之家收集整理的这篇文章主要介绍了php – 在没有SonataUserBundle的Sonata中删除每个用户角色的特定路由前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在Symfony 3中使用了SonataAdminBundle.因为我使用Symfony 3,我仍然无法使用SonataUserBundle.所以我只使用带有FOSUserBundle的SonataAdminBundle.

现在我试图实现的是隐藏每个角色的特定路线.例如,我只有三个角色;

>超级管理员
>管理员
>另一个角色

超级管理员拥有管理员拥有的所有角色,管理员拥有所有第三个角色,第三个显然拥有ROLE_USER.超级管理员应该能够创建新用户并为他分配角色.超级管理员也应该能够更改用户的密码.用户应该能够更改自己帐户的密码.最后,超级管理员不应该更改自己的角色和创建新用户的其他角色.

如何在不使用SonataUserBundle的情况下实现此目的.为了删除路线部分我试过这样的事情:

protected function configureRoutes(RouteCollection $collection)
{
    $securityContext = $this->getConfigurationPool()->getContainer()->get('security.authorization_checker');

    if (!$securityContext->isGranted('ROLE_SUPER_ADMIN')) {
        $collection->remove('create');
        $collection->remove('edit');
    }
}

但我想有一个更好的解决方案.我完全了解official documentation about security,但我对此感到困惑,这是否意味着我必须在我的security.yml文件中对所有不同管理员的每个角色进行硬编码?没有SonataUserBundle,这甚至可以工作吗?我不想为ACL添加额外的数据库表.

有人可以帮助和/或提供一个好例子吗?我会非常感激的.

您可以为User实体定义自定义用户权限选民,请参阅 here.
namespace AppBundle\Security;

use AppBundle\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;

class UserVoter extends Voter
{

    private $decisionManager;

    public function __construct(AccessDecisionManagerInterface $decisionManager)
    {
        $this->decisionManager = $decisionManager;
    }

    protected function supports($attribute,$subject)
    {

        // only vote on User objects inside this voter
        if (!$subject instanceof User) {
            return false;
        }

        return true;
    }

    protected function voteOnAttribute($attribute,$subject,TokenInterface $token)
    {
        // ROLE_SUPER_ADMIN can do anything! The power!
        if ($this->decisionManager->decide($token,array('ROLE_SUPER_ADMIN'))) {
            return true;
        }

        $user = $token->getUser();

        if (!$user instanceof User) {
            // the user must be logged in; if not,deny access
            return false;
        }

        /** @var User $targetUser */
        $targetUser = $subject;

        // Put your custom logic here
        switch ($attribute) {
            case "ROLE_SONATA_ADMIN_USER_VIEW":
                return true;
            case "ROLE_SONATA_ADMIN_USER_EDIT":
                return ($user === $targetUser);
        }
        return false;

    }
}

然后,您创建服务

sonata_admin.user_voter:
    class: AppBundle\Security\UserVoter
    arguments: ['@security.access.decision_manager']
    public: false
    tags:
        - { name: security.voter }

小心access decision strategy,如果定义为一致或共识,我可能无法工作,具体取决于您的配置

如果您不希望为每个用户提供对用户列表的访问权限,您还可以向用户自己的编辑页面添加直接链接/路由.

编辑

要限制用户角色编辑,因为您不希望用户编辑自己的角色,您只需编辑configureFormFields函数

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper
        ->add('username')
        ->add('plainPassword','text',array(
                 'required' => false,)
        )
        /* your other fields */
    ;



    if ($this->isGranted('ROLE_SUPER_ADMIN')) {
        $formMapper->add('roles',\Symfony\Component\Form\Extension\Core\Type\CollectionType::class,array(
            'entry_type'   => \Symfony\Component\Form\Extension\Core\Type\ChoiceType::class,'entry_options'  => array(
                'choices'  => array(
                    "ROLE_OPTICKSB2B" => "ROLE_OPTICKSB2B","ROLE_ADMIN" => "ROLE_ADMIN","ROLE_SUPER_ADMIN" => "ROLE_SUPER_ADMIN"
                ),)
        ));
    }

    $formMapper
        ->add('isActive')
        ->add('title')
        ->add('firstname')
        ->add('lastname')
    ;
}

显然,Symfony表单组件将检查您,而不是添加其他字段.

猜你在找的PHP相关文章