как управлять ролями в Symfony - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть форма регистрации, позволяющая администратору создать пользователя и назначить ему четко определенную роль. после создания, если я пытаюсь соединиться с имеющейся у меня ролью, приложение показывает мне ошибку доступа к ресурсу

secyrity.yaml

security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt
    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        in_memory: { memory: ~ }
        in_database:
            entity:
                class: App\Entity\User
                property: name
    role_hierarchy:
        # Un admin hérite des droits d'utilisateur et de souscommission
        ROLE_ADMIN:       ROLE_SOUSCOMMISSION
        # On garde ce rôle superadmin, il nous resservira par la suite
        #ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: true

            provider:
                in_database

            form_login:
                login_path: security_login
                check_path: security_login
            logout:
                path: security_logout
                target: home

            # activate different ways to authenticate

            # http_basic: true
            # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate

            # form_login: true
            # https://symfony.com/doc/current/security/form_login_setup.html

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }
        - { path: ^/admin/traitement, roles: ROLE_SOUSCOMMISSION }

действий на мой котроллер В моем контроллере я определил его действия

 /**
     * @Route("/inscription", name="security")
    */
    public function inscription(Request $request, ObjectManager $manager, UserPasswordEncoderInterface $encoder)
    {
        $user= new User();
        $form = $this->createForm(UserType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $hash = $encoder->encodePassword($user, $user->getPassword());
            $user->setPassword($hash);
            $manager->persist($user);
            $manager->flush();

            return $this->redirectToRoute('security_login');
        }



        return $this->render('security/inscrie.html.twig', [

            'form' => $form->createView(),
        ]);
    }

     /**
     * @Route("/login", name="security_login")
    */
    public function login(AuthenticationUtils $authenticationUtils)
    {
        $error = $authenticationUtils->getLastAuthenticationError();
        $lastUsername = $authenticationUtils->getLastUsername();

        return $this->render('security/login.html.twig', [ 

        'last_username'=>$lastUsername,

        'error' =>$error
    ]);
}

UserType.php

<?php

namespace App\Form;

use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email')
            ->add('name')
            ->add('password',  PasswordType::class)
            ->add('password_confirme', PasswordType::class)
            ->add('roles', ChoiceType::class, [
                'label' =>'Role',
                'placeholder'=>'',
                'multiple'=>true,
                'choices' =>[
                    'Administrateur'=>'ROLE_ADMIN',
                    'Traiteur ' =>'ROLE_SOUSCOMMISSION',
                ],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class,
        ]);
    }
}

User.php

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints\EqualTo;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 */
class User implements UserInterface
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\EqualTo(propertyPath= "password_confirme")
     */
    private $password;
    /**
     * @Assert\EqualTo(propertyPath= "password", message="Vous n'avez pas taper le meme mot de passe")
     */
    public $password_confirme;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $email;

    /**
     * @ORM\Column(type="array", nullable=true)
     */
    private $roles = [];



    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getPassword(): ?string
    {
        return $this->password;
    }

    public function setPassword(string $password): self
    {
        $this->password = $password;

        return $this;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(string $email): self
    {
        $this->email = $email;

        return $this;
    }


    public function getUserName(){}

    public function eraseCredentials(){}
    public function getSalt(){}

        public function getRoles(){
            return $this->roles;
        }

        public function setRoles(?array $roles): self
        {
            $this->roles = $roles;

            return $this;
        }




}

когда я пытаюсь соединиться с ролью ROLE_SOUCOMMISSION, у меня появляется ошибка типа Отказано в доступе. помогите пожалуйста !!

Ответы [ 2 ]

1 голос
/ 13 апреля 2019

просто измените позицию контроля доступа в security.yaml, чтобы добавить доступ к пользователю, имеющему ROLE_SOUSCOMMISSION, потому что:

Symfony начинается сверху списка и останавливается, когда находит первое совпадение

документация: access_control

access_control:
    - { path: ^/admin/traitement, roles: ROLE_SOUSCOMMISSION }
    - { path: ^/admin, roles: ROLE_ADMIN }

спасибо

1 голос
/ 12 апреля 2019

Это потому, что /admin/traitement меньше /admin, поэтому невозможно перейти на эту страницу, потому что вам нужна роль ROLE_ADMIN, чтобы перейти к /admin и после.Вам нужно инвертировать их или установить /admin с ролью ROLE_SOUSCOMMISSION

...