6

I have a big problem with my role_hierarchy,

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

with that, if i got the SUPER_ADMIN role, I will got the ROLE_AUTHOR, ROLE_MODERATOR, ROLE_USER AND ROLE_ADMIN. But my problem it's when I login on my website, if I check the profiler, i can see i got only the ROLE_SUPER_ADMIN, not the others roles, so, can you help me?

my view (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>

my 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 

edit:

my view (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>

my 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 

please answer :)

Stickly
  • 311
  • 1
  • 2
  • 13
  • The hierarchy does not mean, that you are explicitly added to these roles, i.e. that when you check the profiler you don't see all the roles. It only means, that the access is "inherited". In other words, when you restrict access to an action to ROLE_MODERATOR, even though you are not assigned this role, you can still access the action as ROLE_SUPER_ADMIN inherits the access. – dbrumann Jun 13 '12 at 17:25
  • ok, but if i'm doing is_granted('ROLE_MODERATOR'), i will be able to access to it? Like: {% if is_granted('ROLE_MODERATOR') %} moderator {% else %} no moderator {%endif%}, in a twig template, i'll be able to see moderator? – Stickly Jun 13 '12 at 18:02
  • I have just trying this and it's don't works – Stickly Jun 13 '12 at 18:09
  • It works for me. Can you show more details of your security.yml and the controller/view? Maybe the firewall is not configured for the controller you have tested it with? – dbrumann Jun 13 '12 at 18:55
  • Please, I need help, I don't know what I can do. – Stickly Jun 16 '12 at 14:56
  • I posted a step by step instruction (see my answer). I changed the role_hierarchy, but even with the one you specified it works for me. If you want to have a look at the source, I can push the example to github and post the link here... – dbrumann Jun 16 '12 at 16:24

1 Answers1

10

I cannot see what's wrong from the code snippets you provided, so I made a little example application to give you a step by step-instruction which might lead you to the source of the problem.

  1. Cloned symfony-standard (master) (and removed Acme\DemoBundle)
  2. Added "friendsofsymfony/user-bundle": "dev-master" to composer.json
  3. Created new bundle Mahok\SecurityBundle (php app/console generate:bundle)
  4. Created new Entity php app/console doctrine:generate:entity
  5. Modified Entity according to FOS\UserBundle documentation (step 3; Important: Change the table name to something other than "user", as this is a reserved word and might cause trouble!)
  6. Modified app/AppKernel.php, app/config/config.yml, app/config/routing.yml and app/config/security.yml according to FOS\UserBundle documentation. For reference: This is the security.yml I use:

    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 }
    
  7. Created user with `php app/console fos:user:create sa --super-admin

  8. Modified DefaultController:default.html.twig in Mahok\SecurityBundle, checking for {% 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 %}
    

edit: When going to localhost/example/app_dev.php/hello/User (after logging in as "sa"), I get the following output:

Hello User!
* ROLE_SUPER_ADMIN
* ROLE_USER
dbrumann
  • 16,803
  • 2
  • 42
  • 58
  • I'll try in few hours and I'll post a answer – Stickly Jun 16 '12 at 17:24
  • thanks, but I have anothers questions. in my security.yml, why - { path: ^/admin, role: ROLE_ADMIN } doesn't works? – Stickly Jun 17 '12 at 13:12
  • I assume it's related to your problem with the hierarchy, but as I already wrote, I can't find anything wrong in the code snippets you provided. Removing the unnecessary stuff from security.yml (e.g. the in_memory provider and plaintext-encoder) reduces possible sources for your problem. Other than that you should go through the FOS\UserBundle-documentation and check whether you accidentally missed out a step or made a mistake. For example, see if you extend Entity\User, rather than e.g. Document\User, which can easily happen when you rely on autocomplete in your IDE. – dbrumann Jun 17 '12 at 14:41
  • now, the access control works, but when i'm on my home page, i can't know if i'm connected or not, in the web profiler toolbar, I see anon (for anonymous). I search for how to correct it. – Stickly Jun 17 '12 at 15:16
  • From your example above, this seems implausible. Your main-firewall matches `^/` and anonymous is set to false, so you shouldn't be able to access the home page when you are not logged in. What did you do in order for your access control to work? Please update your question, I'm really curious as how this problem came about. – dbrumann Jun 19 '12 at 09:45
  • omg my access control doesn't work for now, I'll try another thing – Stickly Jun 20 '12 at 02:08
  • in your exemple, why the user sa doesn't got the ROLE_AUTHOR, ROLE_MODERATOR, ROLE_ADMIN? – Stickly Jun 25 '12 at 18:10
  • That's because ROLE_SUPER_ADMIN inherits from ROLE_ADMIN which in turn inherits from ROLE_MODERATOR and so on. If you want to specify each ROLE explicitly, i.e. use the array notation, that should work too, at least it did for me. – dbrumann Jun 26 '12 at 06:09