1

I have a bundle that extends the fos user bundle and an other bundle.
I want once a user is authenticated to redirect him depending on his role admin or simple user to different views.
My problem is that I can not find the controller of the login from where I will do the redirecting.

The role is an attribute of the User entity which comes from the database.

cheesemacfly
  • 11,622
  • 11
  • 53
  • 72
user2269869
  • 181
  • 1
  • 3
  • 15

2 Answers2

10

You've to add a LoginSuccessHandler which implements the AuthenticationSuccessHandler Interface,

You can then set your redirect logic within the onAuthenticationSuccess() method as follow,

namespace XXX\YourBundler\Handler;

use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;

class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
{   
    protected $router;
    protected $security;

    public function __construct(Router $router, SecurityContext $security)
    {
        $this->router   = $router;
        $this->security = $security;
    }
    public function onAuthenticationSuccess(Request $request, TokenInterface $token)
    {   
        if ($this->security->isGranted('ROLE_XXXX_1'))
        {
            $response = new RedirectResponse($this->router->generate('route_1'));           
        }
        elseif ($this->security->isGranted('ROLE_XXXX_2'))
        {
            $response = new RedirectResponse($this->router->generate('route_2'));
        }
        // ...
    } 
}

You handler must also be registered as a service,

parameters:
     security.authentication.success_handler.class: XXX\YourBundler\Handler\AuthenticationSuccessHandler

services:
    security.authentication.customized_success_handler:
        class: %security.authentication.success_handler.class%
        public: false
        arguments:  [@router, @security.context]

You've then to add the following line to your firewall security configuration,

  success_handler: security.authentication.customized_success_handler
Ahmed Siouani
  • 13,701
  • 12
  • 61
  • 72
  • Should I insert the LoginSuccessHandler in the bundle that extends the fos user bundle or in the other one ? @Ahmed Siouani – user2269869 Apr 16 '13 at 08:30
  • How can I affect the roles to the user? @Ahmed Siouani – user2269869 Apr 16 '13 at 08:37
  • You can put it everywhere as it's defined as a service. To load users with their groups(roles) from a database take a deeper look at [How to load Security Users from the Database (the Entity Provider) section](http://symfony.com/doc/current/cookbook/security/entity_provider.html) of the documentation. – Ahmed Siouani Apr 16 '13 at 09:06
  • I don't have a column role in my table user in the database although it extends the fos user bundle. Is that normal? Second thing, I want to add two roles role_admin and role_user. Is this correct: role_hierarchy: ROLE_ADMIN: ROLE_USER @Ahmed Siouani – user2269869 Apr 16 '13 at 09:15
  • also when I added a role attribute to the user entity, I can no longer insert a new user.@Ahmed Siouani – user2269869 Apr 16 '13 at 09:34
  • also I get this error message : InvalidTypeException: Invalid type for path "security.firewalls.success_handler". Expected array, but got string – user2269869 Apr 16 '13 at 09:42
  • Yes, it's ok to define your roles the way you did it. Also, take a look at [The Entity Provider section](http://symfony.com/doc/2.0/cookbook/security/entity_provider.html) of the cookbook which will help you manage your users and their roles. Also, take a look at [The Security Configuration Reference](http://symfony.com/doc/2.0/reference/configuration/security.html) to figure out how a success_handler should be added to your firewall. – Ahmed Siouani Apr 22 '13 at 11:08
0

You can overwrite renderLogin function as follows:

class SecurityController extends BaseController
{
/**
 * Renders the login template with the given parameters. Overwrite this function in
 * an extended controller to provide additional data for the login template.
 *
 * @param array $data
 *
 * @return \Symfony\Component\HttpFoundation\Response
 */
protected function renderLogin(array $data)
{
    $securityContext = $this->get('security.context');
    $router = $this->container->get('router');
//        if ($this->get('security.context')->getToken()->getUser() instanceof \FOS\UserBundle\Propel\User) {
//            $url = $this->container->get('router')->generate('dashboard');
//            return new RedirectResponse($url);
//        }
    if ($securityContext->isGranted('ROLE_ADMIN')) {
        return new RedirectResponse($router->generate('dashboard'), 307);
    }

    if ($securityContext->isGranted('ROLE_USER')) {
        return new RedirectResponse($router->generate('front_page_home'), 307);
    }

    $requestAttributes = $this->container->get('request')->attributes;
    if ($requestAttributes->get('_route') == 'admin_fos_user_security_login') {
        $template = sprintf('FOSUserBundle:Security:login.html.twig');
        $data['admin'] = true;
    } else {
        $template = sprintf('FOSUserBundle:Security:login.html.twig');
        $data['admin'] = false;
    }

    return $this->container->get('templating')->renderResponse($template, $data);
}


}
deyvw
  • 820
  • 7
  • 9