Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony: Firewalls, multiple login forms

Tags:

symfony

I am not new to symfony by any means, but I've always used FOSUserBundle which by default prevents one from having 2 different login forms for authenticating two different user types..

I have two entities, one is Admins and the other is Users. Admins will only be able to login in the administration area and likewise users will only be able to login via the front end.

I've followed: http://symfony.com/doc/2.1/book/security.html which also lead me to http://symfony.com/doc/2.1/cookbook/security/entity_provider.html

My security.yml is:

jms_security_extra:
    secure_all_services: false
    expressions: true

security:
    encoders:
        Symfony\Component\Security\Core\User\User: sha512
        Fm\AdminBundle\Entity\Admins: sha512
        Fm\MainBundle\Entity\Users: sha512

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

    providers:
        chain_provider:
            chain:
                providers: [in_memory, admin]
        in_memory:
            memory:
                users:
                    user:  { password: userpass, roles: [ 'ROLE_USER' ] }
                    admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }

        admin:
            entity: { class: Fm\AdminBundle\Entity\Admins, property: username }


    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
            anonymous: true

        alogin:
            pattern:  ^/admin/login
            security: false
        login:
            pattern:  ^/login
            security: false
        secured_area:
            pattern:    ^/admin
            anonymous: false
            provider: chain_provider
            switch_user: true
            form_login:
                check_path: /admin/login_check
                login_path: /admin/login
            logout:
                path:   /admin/logout
                target: /admin
        members_area:
            pattern: ^/
            anonymous: false
            form_login: ~
            logout:
                path: /logout
                target: /
            #anonymous: ~
            #http_basic:
            #    realm: "Secured Demo Area"

    access_control:
        - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, roles: ROLE_ADMIN }

In my routes I have defined the routes as in the docs: (defaults to /admin/login and /admin/login_check because of my main routing include where /admin is set)

_admin_login:
    pattern:   /login
    defaults:  { _controller: FmAdminBundle:Security:login }

_admin_login_check:
    pattern:   /login_check

The error that I am getting in the browser is:

Unable to find the controller for path "/admin/login_check". Maybe you forgot to add the matching route in your routing configuration?

The stack trace is telling me: WARNING - Unable to look for the controller as the "_controller" parameter is missing

AND

ERROR - Symfony\Component\HttpKernel\Exception\NotFoundHttpException: Unable to find the controller for path "/admin/login_check". Maybe you forgot to add the matching route in your routing configuration? (uncaught exception) at /var/www/mysite.dev/symfony/app/bootstrap.php.cache line 1419

like image 687
Justin Avatar asked Mar 12 '13 16:03

Justin


Video Answer


2 Answers

The problem is that after logging into the "secured_area" firewall you get redirect to "/" which is behind the "members_area" firewall. You can't access "members_area" with your credentials from "secured_area" (at least not by default). Read the details on http://symfony.com/doc/current/reference/configuration/security.html#reference-security-firewall-context .

If you have a look at the security configuration (http://symfony.com/doc/current/reference/configuration/security.html) you can see that the default_target_path for form_login is "/". Just change this to /admin:

security:
    ...

    firewalls:
    ...
        secured_area:
            pattern:    ^/admin
            ...
            form_login:
                check_path: /admin/login_check
                login_path: /admin/login
                default_target_path: /admin
            logout:
    ...

The alternative is to share the context as described in the first link (http://symfony.com/doc/current/reference/configuration/security.html#reference-security-firewall-context).

like image 192
hacfi Avatar answered Sep 30 '22 14:09

hacfi


For implementing multiple login in symfony 2XX, try the following code

Security.yml

security:
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext
        Company\AngularBundle\Entity\User: plaintext
        Company\AngularBundle\Entity\Admin: plaintext

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

    providers:
       users:
           entity: { class: CompanyAngularBundle:User, property: username }
       admin:
           entity: { class: CompanyAngularBundle:Admin, property: username }

    firewalls:
        admin_secured_area:
            pattern:   ^/admin
            anonymous: ~
            provider: admin
            form_login:
                login_path: /admin/login
                check_path: /admin/login_check
                default_target_path: /admin

        user_secured_area:
            pattern:   ^/
            anonymous: ~
            provider: users
            form_login:
                login_path: login
                check_path: login_check
                default_target_path: /home

routing.yml

login_check:
    path: /login_check
admin_login_check:
   path: /admin/login_check

Twig file

Action of login form should be like this
<form action="{{ path('login_check') }}" method="post">

Action of admin/login form should be like this
<form action="{{ path('admin_login_check') }}" method="post">
like image 31
Binu V Pillai Avatar answered Sep 30 '22 14:09

Binu V Pillai