如何在Symfony2中检查表单生成器中的用户角色?

Spl*_*nia 11 role formbuilder symfony

好的,我正在尝试检查用户是否具有特定角色,我这样做

但是,当我这样做时:

public function buildForm(FormBuilder $builder, array $options)
{
    $builder
        ->add('nombre',null,array('label' => 'Usuario'))
        ->add('email')
        ->add('password', 'repeated', array(
            'type' => 'password',
            'invalid_message' => 'Los campos deben coincidir',
            'first_name' => 'password',
            'second_name' => 'confirmar password',
            'options' => array('required' => false)
            ))

        ->add('cliente', 'entity', array(
        'class' => 'ClientesBundle:Cliente',
        'empty_value' => 'Company',            
        'required'    => false,
        'empty_data'  => null)
    **)**
      $user = $this->securityContext->getToken()->getUser();
      **if ($user->getRol() == 'ROLE_SUPER_ADMIN'){**
        ->add('rol') 
        **}**
    ;

}
Run Code Online (Sandbox Code Playgroud)

尝试过这个:

 **if ($this->securityContext->getToken()->getUser()->getRol() === 'ROLE_SUPER_ADMIN'){**
            ->add('rol') 
            **}**
Run Code Online (Sandbox Code Playgroud)

粗体线条(带有**的线条)有一条小红线表示错误,如果......我怎么解决这个问题呢?

Vit*_*ian 15

从控制器,您必须将用户对象传递给表单构建器

$form = $this->createForm(
    new YourType(), 
    $data, 
    array('user' => $this->getUser())
);
Run Code Online (Sandbox Code Playgroud)

然后在表单构建器中,您可以从$options以下位置获取它:

public function buildForm(FormBuilder $builder, array $options)
{
    $user = $options['user']
}
Run Code Online (Sandbox Code Playgroud)

不要忘记setDefaultOptions()user索引扩展:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        ...
        'user' => null
    ));
}
Run Code Online (Sandbox Code Playgroud)

  • 对于SF3使用:`public function configureOptions(OptionsResolver $ resolver)`而不是`setDefaultOptions(OptionsResolverInterface $ resolver)` (2认同)

mav*_*ato 15

如果将表单类型声明为服务,则可以在类中注入令牌存储.

所以你这样声明服务services.yml:

my_form:
    class: AppBundle\Services\MyFormType
    public: true
    arguments:  ['@security.token_storage']
Run Code Online (Sandbox Code Playgroud)

像这样的表单类:

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;

class MyFormType extends AbstractType
{
    protected $tokenStorage;

    public function __construct(TokenStorage $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $user = $this->tokenStorage->getToken()->getUser();
        // Use the user object to build the form
    }
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*Hat 8

I know this is an old question, but I'd like to put forward a better alternative for checking roles inside a form type.

The issue

The issue with using the TokenInterface and the User object is that it does not check for inheritance. For example, consider the following security.yml:

security:
    role_hierarchy:
        ROLE_ADMIN: ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN
Run Code Online (Sandbox Code Playgroud)

If your user has ROLE_SUPER_ADMIN but not ROLE_ADMIN added to their roles, the above solutions will fail if you are using $user->hasRole('ROLE_ADMIN'), as the user does not explicitly have ROLE_ADMIN assigned to their user and hasRole() does not check hierarchy.


The solution

Use the AuthorizationCheckerInterface instead to gain access to the isGranted() function.

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class MyFormType extends AbstractType {

    protected $auth;

    public function __construct(AuthorizationCheckerInterface $auth) {
        $this->auth = $auth;
    }

    public function buildForm(FormBuilderInterface $builder, array $options) {

        // ...

        if($this->auth->isGranted('ROLE_ADMIN')) {
            // Do the thing here
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这将尊重中定义的任何层次结构security.yml。如果我们使用与上述相同的yml文件,则在用户尚未分配个人资料的情况下$auth->isGranted('ROLE_ADMIN')返回trueROLE_SUPER_ADMINROLE_ADMIN