0

I've to set dynamic role to an user when he logs in, so I've created a service LoginSuccessHanlder with this function on login success :

public function onAuthenticationSuccess(Request $request, TokenInterface $token) {
    $response = null;

    $user = $this->token->getToken()->getUser();
    $poste = $request->get('_poste');
    $user->addRole('ROLE_'.strtoupper($poste));
    $this->em->persist($user);
    $this->em->flush();
    if ($this->authorizationChecker->isGranted('ROLE_USER')) {
        $response = new RedirectResponse($this->router->generate('homepage'));
        $response->headers->setCookie(new Cookie('poste', $poste));
    }

    return $response;
}

So here, I add a new role to the user thanks to a field in the login form _poste . Once I'm logged in I should be able to do :

{% if is_granted("ROLE_FLEX") %}
    message
{% endif %}

But there is no message

But if I do this :

{{ dump(app.user.roles) }}

I have in the array the role ROLE_FLEX, why I can't check the role with is_granted function ? What did I missed ?

For information, I'm using FOSUserBundle

EDIT

I remove the role each time that the user logout so when a user logout he doesn't have the ROLE_FLEX anymore but the role will be added if he check this role on log in. Basically the user has a role for each session

Simon M.
  • 2,244
  • 3
  • 17
  • 34
  • Can you show the `addRole` function code? – i.am.michiel Apr 12 '17 at 12:10
  • @i.am.michiel the `addRole` function is provided by the FOSUserBundle – Simon M. Apr 12 '17 at 12:15
  • Are the roles persisted? On every request, the FOSUserBundle reloads the user and roles from the database (or whatever your provider is). – i.am.michiel Apr 12 '17 at 12:20
  • only as test, if the user do a logout then relog into the system, the message appear (the check go fine)? – Matteo Apr 12 '17 at 12:33
  • @i.am.michiel Yes, I've checked in my db when I log in and the role are persisted – Simon M. Apr 12 '17 at 12:51
  • @Matteo No the message still doesn't appear – Simon M. Apr 12 '17 at 12:54
  • Use the web debug toolbar to look at your security session data. Is ROLE_FLEX in it? Symfony actually uses a security token when checking permissions. The token basically has a copy of the roles. I can understand have a problem within the same request. But logging out then logging back in really should work. – Cerad Apr 12 '17 at 13:18
  • Also, why are you using $this->token->getToken() instead of just the passed $token? Copy paste error? – Cerad Apr 12 '17 at 13:19
  • @Cerad The thing is that I remove the role when the user logout because I need to set a different role that depends on a select on the form login, but this shouldn't impact on the user when he is logged in. I've found another solution, but thanks for the help :) – Simon M. Apr 12 '17 at 13:51

2 Answers2

1

The RoleVoter class that is used by the Symfony Security layer when you pass a role to the is_granted() function reads the roles from the token and not the user object. This means that you will have to update the token accordingly too.

xabbuh
  • 5,801
  • 16
  • 18
  • Thanks, this solves my problem ! I used [this](http://stackoverflow.com/questions/19713802/symfony-2-3-how-do-i-refresh-the-authenticated-user-from-the-database) question to refresh the token – Simon M. Apr 14 '17 at 07:54
0

The solution that I found was to create my own function to check If a user have a specific role :

public function isGranted($role)
{
    return in_array($role, $this->getRoles());
}

now I can use {% if app.user.isGranted("ROLE_FLEX") %}

Simon M.
  • 2,244
  • 3
  • 17
  • 34
  • 1
    Just make a note that you are bypassing the security system when you do this. If you ever decide to use things like voters and what not then you will run into trouble. – Cerad Apr 12 '17 at 13:59
  • @Cerad I didn't found other solution for now since I remove the role when the user logout – Simon M. Apr 12 '17 at 14:56