How to debug (and fix) Symfony2|3 routes?

2019-09-02 15:50发布

问题:

I have this routes defined at app/config/routing.yml in a Symfony 2.8 app:

platform_chat:
    resource: "@PlatformChatBundle/Controller/"
    type:     annotation
    prefix:   /chat

platform_admin:
    resource: "@PlatformAdminBundle/Controller/"
    type:     annotation
    prefix:   /admin

#----> this is part of routing.yml but I forgot to add it
easy_admin_bundle:
    resource: "@PlatformAdminBundle/Controller/AdminController.php"
    type:     annotation
    prefix:   /admin

#FOSUser
fos_user:
    resource: "@FOSUserBundle/Resources/config/routing/all.xml"

As you may already notice PlatformAdminBundle is the backend and PlatformChatBundle is the frontend. Having that in mind I am tryin to setuo and use one firewall for both and then on security.interactive_login event redirect to right route|path. This is how the firewall looks like:

security:
    ...
    role_hierarchy:
        ROLE_CHATTER:     ROLE_USER
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN
    ...
    firewalls:
        ...
        ignored:
            pattern: ^/(login(_check)?|logout|resetting)$
            security: false
        global:
            pattern: ^/admin/(.*)|^/chat/(.*)
            provider: fos_userbundle
            form_login:
                csrf_provider: security.csrf.token_manager
                login_path: fos_user_security_login
                check_path: fos_user_security_check
                # if true, forward the user to the login form instead of redirecting
                use_forward: true
                # login success redirecting options (read further below)
                always_use_default_target_path: true
                default_target_path: /admin
                target_path_parameter: _target_path
                use_referer: true
                remember_me: true
            logout: ~
            remember_me:
                secret:   '%secret%'
                lifetime: 604800 # 1 week in seconds
                path:     /

    access_control:
        - { path: ^/chat/, role: ROLE_CHATTER }
        - { path: ^/admin/, role: ROLE_ADMIN }

But it's not working because when I try to login as either user I end with this error:

You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.

Which makes me think that routes or firewall aren't properly configured. I have checked the routes under debug toolbar and none matches so they are wrong complete. I have read docs here but it's not helpful at all and I am not getting the fix for the problem. You can take this post as a second part of this one but I don't want to change the topic of the old one and neither the content because I think it will be helpful on the future for somebody else. So, any advice guys? What would you debug this kind of issues related to routes? Any fix for my particular problem? I am really stuck here!

Update

I have made the changes as @xabbuh suggested so now app/config/routing.yml looks like:

platform_chat:
    resource: "@PlatformChatBundle/Controller/"
    type:     annotation
    prefix:   /chat
    options:
            expose: true

platform_admin:
    resource: "@PlatformAdminBundle/Controller/"
    type:     annotation
    prefix:   /admin
    options:
        expose: true

#EasyAdminBundle
easy_admin_bundle:
    resource: "@PlatformAdminBundle/Controller/AdminController.php"
    type:     annotation
    prefix:   /admin
    options:
        expose: true

#FOSUser
fos_user:
    resource: "@FOSUserBundle/Resources/config/routing/all.xml"

#FOSUser Groups
fos_user_group:
    resource: "@FOSUserBundle/Resources/config/routing/group.xml"
    prefix: /group

#FOSJsRouting
fos_js_routing:
    resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml"

and `` looks like:

security:
    ...
    firewalls:
        ...
        global:
            pattern: /
            anonymous: true
            provider: fos_userbundle
            form_login:
                csrf_provider: security.csrf.token_manager
                login_path: fos_user_security_login
                check_path: fos_user_security_check
                use_forward: true # if true, forward the user to the login form instead of redirecting
                always_use_default_target_path: true # login success redirecting options (read further below)
                default_target_path: /admin
                target_path_parameter: _target_path
                use_referer: true
                remember_me: true
            logout: ~
            remember_me:
                secret:   '%secret%'
                lifetime: 604800 # 1 week in seconds
                path:     /

    access_control:
        - { path: ^/chat/, role: ROLE_CHATTER }
        - { path: ^/admin/, role: ROLE_ADMIN }

after clear the cache here are my tries and results:

  • Login as ROL_CHATTER: I am going to http://domain.tld/app_dev.php/chat/ as expected I get the login form and using valid credentials I get the following message: Access Denied. You are CHATTER. This is right because I have a listener on security.interactive_login and that is what I am doing when user login with those creds.
  • Login as ROL_ADMIN: I am going to http://domain.tld/app_dev.php/admin/ as expected I get the login form and using valid credentials I get the following message: Bad credentials. This is wrong because credentials are valid and at least I should get another message (Access Denied. You are ADMIN) because the listener on security.interactive_login but as I said this is not what is happening.

Info related to the listener is on this post. What's wrong?

回答1:

Your issue is that the regex used to match requests for the global firewall is /admin/(.*)|^/chat/(.*), but your check path is /login_check. As you can see that path would not be matched by your firewall which leads to the error message you posted.

If I were you, I would simply drop the firewall fore the login related stuff and change the regex for the global firewall to /. You would then only have to add anonymous: true so that users that are not logged in would be able to access the login form. Access to your protected areas would still be denied by your access control section.