Symfony2 的角色层次结构

Posted

技术标签:

【中文标题】Symfony2 的角色层次结构【英文标题】:role_hierarchy with Symfony2 【发布时间】:2012-06-16 17:01:27 【问题描述】:

我的 role_hierarchy 有一个大问题,

security:
    role_hierarchy:
        ROLE_ADMIN:[ROLE_USER,ROLE_AUTHOR,ROLE_MODERATOR]
        ROLE_SUPER_ADMIN:[ROLE_ADMIN,ROLE_ALLOWED_TO_SWITCH]

这样,如果我获得了 SUPER_ADMIN 角色,我将获得 ROLE_AUTHOR、ROLE_MODERATOR、ROLE_USER 和 ROLE_ADMIN。但是我的问题是当我登录我的网站时,如果我检查分析器,我可以看到我只有 ROLE_SUPER_ADMIN,而不是其他角色,所以,你能帮帮我吗?

我的看法 (base.html.twig)

<h3>Blog</h3>
<ul class="nav nav-pills nav-stacked">
    <li><a href=" path('dom_home') ">Home Page</a></li>
    % if is_granted('ROLE_AUTHOR') %
        <li><a href=" path('dom_add') ">Add a post</a></li>
    % endif %
    % if is_granted('IS_AUTHENTICATED_FULLY') %
        <li><a href=" path('fos_user_security_logout') ">Logout</a></li>
    % else %
        <li><a href=" path('fos_user_security_login') ">login</a></li>
        <li><a href=" path('fos_user_registration_register') ">register</a></li>
    % endif %
</ul>

我的security.yml(应用程序/配置)

security:
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext
        FOS\UserBundle\Model\UserInterface: sha512

    role_hierarchy:
        ROLE_ADMIN:       [ROLE_USER,ROLE_AUTHOR,ROLE_MODERATOR]
        ROLE_SUPER_ADMIN: [ROLE_ADMIN,ROLE_ALLOWED_TO_SWITCH]

    providers:
        in_memory:
            users:
                user:   password: userpass, roles: [ 'ROLE_USER' ] 
                admin:  password: adminpass, roles: [ 'ROLE_ADMIN' ] 
        fos_userbundle:
            id: fos_user.user_manager
    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
        login:
            pattern:   ^/(login$|register|resetting)
            anonymous: true
        main:
            pattern: ^/
            form_login:
                provider:    fos_userbundle
                remember_me: true
                always_use_default_target_path: true
                default_target_path: /dom/
            remember_me:
                key:         %secret%
            anonymous:       false
            logout:          true 

编辑:

我的观点(base.html.twig)

<h3>Blog</h3>
<ul class="nav nav-pills nav-stacked">
    <li><a href=" path('dom_home') ">Home Page</a></li>
    % if is_granted('ROLE_AUTHOR') %
        <li><a href=" path('dom_add') ">Add a post</a></li>
    % endif %
    % if is_granted('IS_AUTHENTICATED_FULLY') %
        <li><a href=" path('fos_user_security_logout') ">Logout</a></li>
    % else %
        <li><a href=" path('fos_user_security_login') ">login</a></li>
        <li><a href=" path('fos_user_registration_register') ">register</a></li>
    % endif %
</ul>

我的 security.yml (app/config)

security:
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext
        FOS\UserBundle\Model\UserInterface: sha512

    role_hierarchy:
        ROLE_ADMIN:       [ROLE_USER,ROLE_AUTHOR,ROLE_MODERATOR]
        ROLE_SUPER_ADMIN: [ROLE_ADMIN,ROLE_ALLOWED_TO_SWITCH]

    providers:
        in_memory:
            users:
                user:   password: userpass, roles: [ 'ROLE_USER' ] 
                admin:  password: adminpass, roles: [ 'ROLE_ADMIN' ] 
        fos_userbundle:
            id: fos_user.user_manager
    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
        login:
            pattern:   ^/(login$|register|resetting)
            anonymous: true
        main:
            pattern: ^/
            form_login:
                provider:    fos_userbundle
                remember_me: true
                always_use_default_target_path: true
                default_target_path: /dom/
            remember_me:
                key:         %secret%
            anonymous:       false
            logout:          true 

请回答:)

【问题讨论】:

层次结构并不意味着您被明确添加到这些角色中,即当您检查分析器时,您看不到所有角色。这只意味着,访问是“继承的”。换句话说,当您将某个操作的访问权限限制为 ROLE_MODERATOR 时,即使您没有被分配此角色,您仍然可以访问该操作,因为 ROLE_SUPER_ADMIN 继承了访问权限。 好的,但是如果我正在做 is_granted('ROLE_MODERATOR'),我将能够访问它吗?比如:% if is_granted('ROLE_MODERATOR') % 版主 % else % 没有版主 %endif%,在树枝模板中,我就能看到版主? 我刚刚尝试过,它不起作用 它对我有用。你能展示你的security.yml和控制器/视图的更多细节吗?可能没有为您测试过的控制器配置防火墙? 拜托,我需要帮助,我不知道我能做什么。 【参考方案1】:

我看不出您提供的代码 sn-ps 有什么问题,所以我制作了一个小示例应用程序,为您提供逐步说明,可能会引导您找到问题的根源。

    克隆的 symfony-standard(主)(并删除了 Acme\DemoBundle) 在 composer.json 中添加了"friendsofsymfony/user-bundle": "dev-master" 创建了新的捆绑包 Mahok\SecurityBundle (php app/console generate:bundle) 创建了新实体php app/console doctrine:generate:entity 根据 FOS\UserBundle 文档修改实体(第 3 步;重要提示:将表名更改为“user”以外的名称,因为这是保留字,可能会引起麻烦!)

    根据 FOS\UserBundle 文档修改了 app/AppKernel.phpapp/config/config.ymlapp/config/routing.ymlapp/config/security.yml。供参考:这是我使用的security.yml:

    jms_security_extra:
        secure_all_services: false
        expressions: true
    
    security:
        encoders:
            FOS\UserBundle\Model\UserInterface: sha512
    
    role_hierarchy:
        ROLE_AUTHOR:      [ROLE_USER]
        ROLE_MODERATOR:   [ROLE_AUTHOR]
        ROLE_ADMIN:       [ROLE_MODERATOR]
        ROLE_SUPER_ADMIN: [ROLE_ADMIN]
    
    providers:
        fos_userbundle:
            id: fos_user.user_manager
    
    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
    
        auth:
            pattern:   (^/login$|^/register|^/resetting)
            anonymous: true
    
        main:
            pattern:    ^/
            form_login:
                provider:      fos_userbundle
                csrf_provider: form.csrf_provider
            logout:     true
            anonymous:  true
    
    access_control:
        -  path: ^/admin, role: ROLE_ADMIN 
    

    使用 `php app/console fos:user:create sa --super-admin 创建用户

    在 Mahok\SecurityBundle 中修改 DefaultController:default.html.twig,检查 % is_granted('ROLE_MODERATOR') %:

    Hello  name !
    % if is_granted('ROLE_MODERATOR') %
    <ul>
        % for role in app.user.roles %
        <li> role </li>
        % endfor %
    </ul>
    % else %
        oh noes!
    % endif %
    

编辑: 当转到 localhost/example/app_dev.php/hello/User 时(以“sa”身份登录后),我得到以下输出:

Hello User!
* ROLE_SUPER_ADMIN
* ROLE_USER

【讨论】:

我会在几个小时内尝试,我会发布答案 谢谢,但我还有其他问题。在我的 security.yml 中,为什么 - path: ^/admin, role: ROLE_ADMIN 不起作用? 我认为这与您的层次结构问题有关,但正如我已经写过的,我在您提供的代码 sn-ps 中找不到任何错误。从 security.yml 中删除不必要的东西(例如 in_memory 提供程序和纯文本编码器)可以减少问题的可能来源。除此之外,您应该查看 FOS\UserBundle-documentation 并检查您是否不小心错过了一步或犯了错误。例如,看看你是否扩展了 Entity\User,而不是 e.g. Document\User,当您依赖 IDE 中的自动完成功能时,很容易发生这种情况。 现在,访问控制工作,但是当我在我的主页上时,我不知道我是否已连接,在网络分析器工具栏中,我看到 anon(匿名)。我正在搜索如何纠正它。 从你上面的例子来看,这似乎不可信。您的主防火墙与^/ 匹配,并且anonymous 设置为false,因此您在未登录时应该无法访问主页。您为使访问控制起作用做了什么?请更新您的问题,我真的很好奇这个问题是如何产生的。

以上是关于Symfony2 的角色层次结构的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Symfony2 中创建和注册新角色

Symfony2 url层次结构

如何在 Symfony 中检索完整的角色层次结构

Symfony2 中 isGranted 的替代方案

Symfony2 在 Twig 中获取用户角色

Symfony2\Doctrine - 检索用户角色