Reputation:
I have looked everywhere, and tried everything, but my redirect still doesn't want to work.
I have done option two of this question's answer but the wanted results doesn't appear.
This is my overwritten login function (inside /src/Acme/UserBundle/Controller/SecurityController.php
);
class SecurityController extends BaseController
{
public function loginAction(Request $request)
{
/** @var $session \Symfony\Component\HttpFoundation\Session\Session */
$session = $request->getSession();
$authChecker = $this->container->get('security.authorization_checker');
$router = $this->container->get('router');
if ($authChecker->isGranted('ROLE_ADMIN')) {
return new RedirectResponse($router->generate('admin_home'), 307);
}
if ($authChecker->isGranted('ROLE_USER')) {
return new RedirectResponse($router->generate('user_home'), 307);
}
...
...
}
}
I have my AcmeUserBundle.php
inside /src/Acme/UserBundle/
containing the following code;
namespace Acme\UserBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AcmeUserBundle extends Bundle
{
public function getParent()
{
return 'FOSUserBundle';
}
}
Then I have my main application bundle AppBundle
next to Acme
inside /src/
with my DefaultController.php
inside /Controller/
and my admin controller as DefaultController.php
inside /Controller/Admin/
When I log in with a user with role ROLE_USER
, it goes to the correct location. But when I log in with role ROLE_ADMIN
he goes to the same location as ROLE_USER
. It is suppose to go to the admin page.
This is my security.yml
file;
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
logout: true
anonymous: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, role: ROLE_USER }
- { path: ^/admin, role: ROLE_ADMIN }
In my project's profiler the user role for a normally registered user state ROLE_USER
. I modified a user's role in my database to be ROLE_ADMIN
and when I log in with him both roles shows to be assigned to him. Under the role
column in my database this is how it looks for a user with ROLE_USER
assigned to him :
a:0:{}
and this is how I modified the other user to have ROLE_ADMIN
:
a:1:{i:0;s:10:"ROLE_ADMIN";}
Is this right? Can somebody please help me to fix this problem?
NOTE: When I sign in with a ROLE_USER
user and I modify the url to go to /admin/ I get a "Expression "has_role('ROLE_ADMIN')" denied access." error. I get that, that's fine because I don't want a normal user to access that area. But when I login with a ROLE_ADMIN
user and modify the url to /admin/ it does go to that page, so I can see by that that my ROLES are working fine and the routing as well, but the redirect on login not.
Clearing my cache also didn't do the trick.
Upvotes: 4
Views: 1066
Reputation: 404
This is how I did it...
// AppBundle\Security\LoginSuccessHandler.php
namespace AppBundle\Security;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface {
protected $router;
protected $authorizationChecker;
public function __construct(Router $router, AuthorizationChecker $authorizationChecker) {
$this->router = $router;
$this->authorizationChecker = $authorizationChecker;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token) {
$response = null;
if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
$response = new RedirectResponse($this->router->generate('admin'));
}
return $response;
}
}
Then add this to your services.yml file:
authentication.handler.login_success_handler:
class: AppBundle\Security\LoginSuccessHandler
arguments: ['@router', '@security.authorization_checker']
I can't remember if there were other steps.. Pretty sure the services file entry takes care of making sure that class gets called.
Upvotes: 2
Reputation: 2966
There is a little known success_handler
option in form_login
(at least), here you can find a gist with example usage suiting your needs just perfectly.
Upvotes: 1