Sonata Admin:isGranted() 在 Admin 类中总是返回 true,但在模板中返回正确的布尔值
Posted
技术标签:
【中文标题】Sonata Admin:isGranted() 在 Admin 类中总是返回 true,但在模板中返回正确的布尔值【英文标题】:Sonata Admin: isGranted() always returns true in Admin class, but correct boolean in template 【发布时间】:2016-09-21 10:34:37 【问题描述】:我在Symfony 2
项目中使用SonataAdminBundle
和SonataUserBundle
。安装的包有:
$ composer show | grep symfony
friendsofsymfony/rest-bundle 1.7.7 This Bundle provides various tools to rapidly develop RESTful API's with Symfony
friendsofsymfony/user-bundle v1.3.6 Symfony FOSUserBundle
symfony/assetic-bundle v2.8.0 Integrates Assetic into Symfony2
symfony/css-selector v2.8.6 Symfony CssSelector Component
symfony/dom-crawler v2.8.6 Symfony DomCrawler Component
symfony/monolog-bundle 2.11.1 Symfony MonologBundle
symfony/polyfill-apcu v1.1.1 Symfony polyfill backporting apcu_* functions to lower php versions
symfony/polyfill-mbstring v1.1.1 Symfony polyfill for the Mbstring extension
symfony/swiftmailer-bundle v2.3.11 Symfony SwiftmailerBundle
symfony/symfony v2.7.13 The Symfony PHP framework
$ composer show | grep sonata
sonata-project/admin-bundle 2.3.10 Symfony SonataAdminBundle
sonata-project/block-bundle 2.2.15 Symfony SonataBlockBundle
sonata-project/cache 1.0.7 Cache library
sonata-project/core-bundle 2.3.11 Symfony SonataCoreBundle
sonata-project/doctrine-extensions 1.0.2 Doctrine2 behavioral extensions
sonata-project/doctrine-orm-admin-bundle 2.3.4 Symfony Sonata / Integrate Doctrine ORM into the SonataAdminBundle
sonata-project/easy-extends-bundle 2.1.10 Symfony SonataEasyExtendsBundle
sonata-project/exporter 1.4.1 Lightweight Exporter library
sonata-project/google-authenticator 1.0.2 Library to integrate Google Authenticator into a PHP project
sonata-project/user-bundle 2.2.5 Symfony SonataUserBundle
security.yml
配置文件中的角色:
role_hierarchy:
ROLE_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN]
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
使用只有ROLE_ADMIN
的用户登录,以下从我的UserAdmin
类转储:
dump($this->isGranted('ROLE_ALLOWED_TO_SWITCH'));
dump($this->isGranted('ROLE_BLA_BLA_BLA'));
dump($this->isGranted('ROLE_USER'));
在 Symfony 工具栏中打印(在 dev
环境中)
true
true
true
如果我将转储文件放在像 app/Resources/SonataAdminBundle/views/CRUD/[anytemplate].html.twig
这样被覆盖的奏鸣曲模板中,
dump(is_granted('ROLE_ALLOWED_TO_SWITCH'))
dump(is_granted('ROLE_BLA_BLA_BLA'))
dump(is_granted('ROLE_USER'))
返回正确的值。
false
false
true
我进入这个是因为SonataUserBundle
中的这一行没有任何效果:https://github.com/sonata-project/SonataUserBundle/blob/3.x/Admin/Model/UserAdmin.php#L95
isGranted()
的用法在此处描述:http://symfony.com/doc/current/bundles/SonataAdminBundle/reference/security.html#usage
是我做错了什么还是这是一个错误?
编辑:
感谢@mickadoo 的评论,我注意到我有默认处理程序sonata.admin.security.handler.noop
,据说它总是返回true
,不管这意味着什么。我用sonata.admin.security.handler.role
设置它并创建了一些角色(ROLE_SONATA_USER_ADMIN_USER_LIST
和ROLE_SONATA_USER_ADMIN_USER_VIEW
),现在它为$this->isGranted('LIST')
或$this->isGranted('VIEW')
返回正确的值,但对于$this->isGranted('ROLE_USER')
或@987654349 总是返回false
@。
如何查看这个角色?
【问题讨论】:
您是否将您的 access_decision_strategy 设置为一致,如此处所述? symfony.com/doc/current/bundles/SonataAdminBundle/reference/… 谢谢!它没有太大变化,但帮助我注意到我正在使用默认处理程序sonata.admin.security.handler.noop
。我编辑了问题以提供更多信息。
很高兴听到它对您有所帮助。就像我说的,我对奏鸣曲没有经验,但我没有看到任何用法检查文档页面中的纯粹角色。你试过$this->get('security.authorization_checker')->isGranted('ROLE_USER'))
吗?如果您只想检查用户是否有角色,您可以随时使用RoleHierarchy
创建服务来检查可访问角色是否包含您要检查的角色,但这可能不是最干净的方法。如果您可以调试并检查 AccessDecisionManager
投票者中的哪一个返回 false 可能会有所帮助。
【参考方案1】:
通用的、非实体角色,如ROLE_USER
、ROLE_ADMIN
、ROLE_SUPER_ADMIN
、ROLE_CUSTOM_STRING
,应使用默认的 Symfony 安全上下文进行检查。
在Admin
类中:
$securityContext = $this->getConfigurationPool()->getContainer()->get('security.context');
if ($securityContext->isGranted('ROLE_USER'))
// Your PHP code here
在Twig
模板中:
% if is_granted('ROLE_USER') %
Your HTML/Twig content here.
% endif %
实体操作角色,例如ROLE_SONATA_USER_ADMIN_USER_LIST
、ROLE_SONATA_USER_ADMIN_USER_VIEW
、ROLE_CUSTOM_SONATA_ADMIN_SERVICE_NAME_ACTION
,可以使用 Sonata Admin helper 或 Symfony 安全上下文进行检查。
在Admin
类中:
// Using Symfony security context
$securityContext = $this->getConfigurationPool()->getContainer()->get('security.context');
if ($securityContext->isGranted('ROLE_SONATA_USER_ADMIN_USER_LIST'))
// your code here
// Using Sonata helper for shorter syntax
if ($this->isGranted('LIST'))
// your code here
在Twig
模板中:
<!-- Using Symfony security context -->
% if is_granted('ROLE_SONATA_USER_ADMIN_USER_LIST') %
Your HTML/Twig content here.
% endif %
<!-- Using Sonata helper -->
% if admin.isGranted('LIST') %
Your HTML/Twig content here.
% endif %
【讨论】:
在 Admin 类中使用$securityContext = $this->getConfigurationPool()->getContainer()->get('security.context');
时出现错误:You have requested a non-existent service "security.context".
请告知
没关系。我想到了。 security.context
一直使用到 Symfony 2.5。从 Symfony 2.6 开始,security.context
服务已被弃用,现在我们必须改用 security.authorization_checker
。像这样; $securityContext = $this->getConfigurationPool()->getContainer()->get('security.authorization_checker');
尝试在管理类中使用 authorization_checker 时出现此错误“令牌存储不包含身份验证令牌。一个可能的原因可能是在 . 中没有为此 URL 配置防火墙(正在导入来自“app/config/routing.yml”)。确保有一个支持“sonata_admin”类型的加载器。”并且令牌为NULL,我做错了什么?【参考方案2】:
我现在正在做一个项目,似乎 isGranted 正在管理类中这样做。 我发现的解决方法是在 Admin 类中:
if ($this->getContainer()->get('security.token_storage')->getToken()->getUser()->getRoles()[0] == 'ROLE_EMPLOYEE')
它返回您在创建用户时分配的角色(无继承)。 您当然需要满足继承的需要,因此您必须列出您想要允许或禁止的所有角色,以较少列出的为准。 检查 getUser() 不为空并且 getRoles() 返回一个数组。
【讨论】:
【参考方案3】:这在奏鸣曲管理和 Symfony 4 中对我有用:
/**
* @param string $role
* @return bool
*/
protected function checkUserHasRole(string $role): bool
$securityContext = $this->getConfigurationPool()->getContainer()->get('security.authorization_checker');
try
return $securityContext->isGranted($role);
catch (AuthenticationCredentialsNotFoundException $e)
return false;
【讨论】:
问题是关于 Symfony 2 项目(我已经更新它以反映这一点)。不过,您的回答可能对使用 Symfony 4 的人有用。感谢您发布它。以上是关于Sonata Admin:isGranted() 在 Admin 类中总是返回 true,但在模板中返回正确的布尔值的主要内容,如果未能解决你的问题,请参考以下文章
Sonata 管理包:无法删除与 sonata_type_admin 的关系
服务“admin.category”依赖于不存在的服务“sonata.admin.manager.orm”
有没有办法确定 Sonata\AdminBundle\Admin\Admin::configureFormFields() 中的当前操作(创建或编辑)?