问题
i have a login form what i want to do that if a user have role user tries to login he's redirected to page voiture_new and if an admin eventually has a role admin he's redirected to the admin page PS : i'm using easyadminbundle
here's what i've added to the loginaction of my controller
$authChecker = $this->container- >get('security.authorization_checker');
$router = $this->container->get('router');
if ($authChecker->isGranted('ROLE_ADMIN')) {
return new RedirectResponse($router->generate('admin'), 307);
}
if ($authChecker->isGranted('ROLE_USER')) {
return new RedirectResponse($router->generate('voiture_new'), 307);
}
and here's my security.yml
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_email
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
always_use_default_target_path: false
default_target_path: /voiture/new
check_path: fos_user_security_check
# if you are using Symfony < 2.8, use the following config instead:
# csrf_provider: form.csrf_provider
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: ^/admin/, role: ROLE_ADMIN }
- { path: ^/marque/, role: ROLE_ADMIN }
- { path: ^/modele/, role: ROLE_ADMIN }
- { path: ^/user/, role: ROLE_ADMIN }
- { path: ^/voiture/, role: ROLE_USER }
- { path: ^/profile/, role: ROLE_USER }
- { path: ^/interventions/, role: ROLE_USER }
but always i'mredirected to voiture_new even if the user have a role admin waht i'm missing ?
回答1:
What you need to do is to create Authenticator Class and then tell symfony that use this while trying to authenticate. Inside this class is a method onAuthenticationSuccess
you can then use this to perform all the redirect.
For example inside security.yml
under firewall which is called main in this case. Tell it that you want to use guard and then mention the service which in this example is called app.form_login_authenticator
main:
pattern: ^/
http_basic: ~
anonymous: ~
logout:
path: logout
guard:
authenticators:
- app.form_login_authenticator
# by default, use the start() function from FormLoginAuthenticator
entry_point: app.form_login_authenticator
Inside your services.yml
make sure this service is listed
app.form_login_authenticator:
class: AppBundle\Security\FormLoginAuthenticator
arguments: ["@service_container"]
and then this is the class example
class FormLoginAuthenticator extends AbstractFormLoginAuthenticator
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function getCredentials(Request $request)
{
if ($request->getPathInfo() != '/login_check') {
return;
}
$username = $request->request->get('_username');
$request->getSession()->set(Security::LAST_USERNAME, $username);
$password = $request->request->get('_password');
return array(
'username' => $username,
'password' => $password
);
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$username = $credentials['username'];
$userRepo = $this->container
->get('doctrine')
->getManager()
->getRepository('AppBundle:User');
return $userRepo->findOneByUsername($username);
}
public function checkCredentials($credentials, UserInterface $user)
{
$plainPassword = $credentials['password'];
$encoder = $this->container->get('security.password_encoder');
if (!$encoder->isPasswordValid($user, $plainPassword)) {
return false;
}
return true;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
// AJAX! Maybe return some JSON
if ($request->isXmlHttpRequest()) {
return new JsonResponse(
// you could translate the message
array('message' => $exception->getMessageKey()),
403
);
}
// for non-AJAX requests, return the normal redirect
return parent::onAuthenticationFailure($request, $exception);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
//Perform your redirects here for example
$response = '';
if($this->container->get('security.authorization_checker')->isGranted('ROLE_ADMIN')){
$response = $this->container->get('router')->generate('admin_dashboard');
}
if($this->container->get('security.authorization_checker')->isGranted('ROLE_USER')){
$response = $this->container->get('router')->generate('user_dashboard');
}
return $response;
}
protected function getLoginUrl()
{
return $this->container->get('router')
->generate('login');
}
}
Hopefully this should put you in right path to implementing what you are looking for,
来源:https://stackoverflow.com/questions/43443860/symfony-fosuserbundle-redirection-after-login