Use the same provider for multiple forms

0

In the application there are 2 login forms, one for clients and one for administrators.

The 2 forms use the same provider:

 security:
     providers:
        form_login:
            entity: { class: FMP\SecurityBundle\Entity\User, property: username }

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

    app_secured_area:
        pattern: ^/
        anonymous: ~
        form_login:
            provider: form_login
            login_path: security_app_login
            check_path: security_app_login_check
            default_target_path: /
        logout:
            path: security_logout
            target: security_app_login

    admin_secured_area:
          pattern: ^/admin
          anonymous: ~
          form_login:
              provider: form_login
              login_path: security_admin_login
              check_path: security_admin_login_check
              default_target_path: /admin/
          logout:
              path: security_logout
              target: security_admin_login

    default:
        anonymous: ~
        http_basic: ~

I have DefaultController.php structured as follows:

class DefaultController extends Controller
{
    /**
     * @Route("/login", name="security_app_login")
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\Response
     */
     public function appLoginAction(Request $request)
     {
        return $this->loginAction($request, 'FMPSecurityBundle:Default:app_login.html.twig');
     }

     /**
      * @Route("/admin/login", name="security_admin_login")
      * @param Request $request
      * @return \Symfony\Component\HttpFoundation\Response
      */
      public function adminLoginAction(Request $request)
      {
           return $this->loginAction($request, 'FMPSecurityBundle:Default:admin_login.html.twig');
      }

      public function loginAction(Request $request, $template)
      {
          $session = $request->getSession();

          if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
              $error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
          } else {
               $error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
          }

          return $this->render($template, array(
              'last_username' => $session->get(SecurityContext::LAST_USERNAME),
              'error'         => $error,
          ));
      }

      /**
       * @Route("/login_check", name="security_app_login_check")
       */
      public function loginCheckAppAction()
      {
          //
      }

      /**
       * @Route("/admin/login_check", name="security_admin_login_check")
       */
      public function loginCheckAdminAction()
      {
          //
      }   

      /**
       * @Route("/logout", name="security_logout")
       */
      public function logoutAction()
      {
          //
      }
}

When accessing the /admin/login route and logging in, the following error is returned:

  

The controller must return a response (null given). Did you forget to add a return statement somewhere in your controller?

What's wrong? Can not use the same provider for different forms?

    
asked by anonymous 11.04.2016 / 14:02

1 answer

0

First I changed the check_path property of the 2 firewalls:

check_path: security_login_check

This worked however if the administrator entered the wrong credentials, it will be redirected to the client login form, which is an error.

To resolve this issue, I've changed the order of the firewalls.

Firewalls are called in the order they are defined, if the default does not match Symfony will try the next pattern.

As I first set the ^/ (that is, any request) pattern, it runs first, so Symfony would never execute path ^/admin .

    
11.04.2016 / 17:06