You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Symfony2的security.yml中添加角色并管控SonataAdminBundle仪表盘子菜单显示

Hey there! Let's walk through how to add roles in Symfony2's security.yml and then control SonataAdminBundle submenu visibility based on those roles—super straightforward once you know the steps.

1. Adding Roles in Symfony2's security.yml

Symfony roles follow the ROLE_ naming convention, and you'll configure them in two main places: the role hierarchy (for role inheritance) and user providers (to assign roles to specific users).

Role Hierarchy

If you want roles to inherit permissions from other roles (e.g., ROLE_ADMIN gets all ROLE_USER permissions), define this in the role_hierarchy section. Add your custom role here too—let's say ROLE_SONATA_SUBMENU_ACCESS for your submenu control:

# app/config/security.yml
security:
    role_hierarchy:
        ROLE_EDITOR:       ROLE_USER
        ROLE_ADMIN:        [ROLE_USER, ROLE_EDITOR]
        ROLE_SUPER_ADMIN:  [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
        # Your custom role for Sonata submenu access
        ROLE_SONATA_SUBMENU_ACCESS: ROLE_USER

Assign Roles to Users

You can assign roles directly to users via your user entity (if using a database provider) or in an in-memory provider for testing:

security:
    providers:
        in_memory:
            memory:
                users:
                    john_doe:
                        password: your_encoded_password
                        roles: ['ROLE_USER', 'ROLE_SONATA_SUBMENU_ACCESS']
                    jane_smith:
                        password: another_encoded_password
                        roles: ['ROLE_ADMIN']

2. Controlling SonataAdminBundle Submenu Visibility

There are a few flexible ways to hide/show submenus based on roles—here are the most common and practical approaches:

Approach 1: Control Submenus Directly in Your Admin Class

This is the simplest method if you want granular control over a specific submenu. You'll use Symfony's AuthorizationCheckerInterface to check the user's role and conditionally add the submenu item.

First, inject the authorization checker into your Admin class:

// src/YourBundle/Admin/YourEntityAdmin.php
namespace YourBundle\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Menu\MenuItemInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class YourEntityAdmin extends AbstractAdmin
{
    private $authorizationChecker;

    public function __construct($code, $class, $baseControllerName, AuthorizationCheckerInterface $authorizationChecker)
    {
        parent::__construct($code, $class, $baseControllerName);
        $this->authorizationChecker = $authorizationChecker;
    }

    // Control sidebar submenus
    protected function configureSideMenu(MenuItemInterface $menu, $action, \Sonata\AdminBundle\Admin\AdminInterface $childAdmin = null)
    {
        parent::configureSideMenu($menu, $action, $childAdmin);

        // Only show this submenu to users with ROLE_SONATA_SUBMENU_ACCESS
        if ($this->authorizationChecker->isGranted('ROLE_SONATA_SUBMENU_ACCESS')) {
            $menu->addChild('Your Restricted Submenu', [
                'uri' => $this->generateUrl('list'),
                'attributes' => ['icon' => 'fa fa-list']
            ]);
        }
    }

    // Or control top menu items (if needed)
    public function configureMenuItems(array $menuItems): array
    {
        $menuItems = parent::configureMenuItems($menuItems);

        if ($this->authorizationChecker->isGranted('ROLE_SONATA_SUBMENU_ACCESS')) {
            $menuItems[] = ['label' => 'Custom Top Menu', 'route' => 'your_custom_route'];
        }

        return $menuItems;
    }
}

Approach 2: Restrict Entire Admin Sections to a Role

If you want to hide the entire Admin section (and its submenus) from users without the role, set the security directly in the Admin class:

class YourEntityAdmin extends AbstractAdmin
{
    protected function configure()
    {
        parent::configure();

        // Only users with ROLE_SONATA_SUBMENU_ACCESS can access this Admin section
        $this->setSecurity('ROLE_SONATA_SUBMENU_ACCESS');
    }
}

Approach 3: Global Menu Control with Event Listeners

For more global control (e.g., modifying multiple menus at once), use an event listener to hook into Sonata's menu-building process:

  1. Create the listener class:
// src/YourBundle/EventListener/SonataMenuListener.php
namespace YourBundle\EventListener;

use Sonata\AdminBundle\Event\ConfigureMenuEvent;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class SonataMenuListener
{
    private $authorizationChecker;

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

    public function configureSidebarMenu(ConfigureMenuEvent $event)
    {
        $menu = $event->getMenu();

        // Loop through menu items and remove the restricted one if user lacks the role
        foreach ($menu->getChildren() as $child) {
            if ($child->getLabel() === 'Restricted Submenu') {
                if (!$this->authorizationChecker->isGranted('ROLE_SONATA_SUBMENU_ACCESS')) {
                    $menu->removeChild($child);
                }
            }
        }
    }
}
  1. Register the listener in your services:
# app/config/services.yml
services:
    your_bundle.sonata_menu_listener:
        class: YourBundle\EventListener\SonataMenuListener
        arguments: ['@security.authorization_checker']
        tags:
            - { name: kernel.event_listener, event: sonata.admin.event.configure.menu.sidebar, method: configureSidebarMenu }

Quick Recommendation

For most cases, Approach 1 is the best choice—it's simple, targeted, and keeps your menu logic right where it belongs (in the Admin class responsible for that section).

内容的提问来源于stack exchange,提问作者Oumayma Ben Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:27:32