Say for example I grant a new role to the currently authenticated user in a controller, like so:
$em = $this->getDoctrine()->getManager();
$loggedInUser = $this->get('security.context')->getToken()->getUser();
$loggedInUser->addRole('ROLE_XYZ');
$em->persist($loggedInUser);
$em->flush();
On the next page load, when I grab the authenticated user again:
$loggedInUser = $this->get('security.context')->getToken()->getUser();
They are not granted the role. I am guessing this is because the user is stored in the session and needs to be refreshed.
How do I do this?
I am using FOSUserBundle if that makes a difference.
EDIT: This question was originally asked in the context of Symfony version 2.3 but there are answers for more recent versions below as well.
Try this:
$em = $this->getDoctrine()->getManager();
$loggedInUser = $this->get('security.context')->getToken()->getUser();
$loggedInUser->addRole('ROLE_XYZ');
$em->persist($loggedInUser);
$em->flush();
$token = new \Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken(
$loggedInUser,
null,
'main',
$loggedInUser->getRoles()
);
$this->container->get('security.context')->setToken($token);
There's no need for the token reset in the previous answer. Just, in your security config file (security.yml, etc...), add this:
security:
always_authenticate_before_granting: true
While an answer is accepted, Symfony actually has a native way to refresh the User object. Credit goes out to Joeri Timmermans for this article.
Steps for refreshing the User object:
Symfony\Component\Security\Core\User\EquatableInterface
public function isEqualTo(UserInterface $user)
{
if ($user instanceof User) {
// Check that the roles are the same, in any order
$isEqual = count($this->getRoles()) == count($user->getRoles());
if ($isEqual) {
foreach($this->getRoles() as $role) {
$isEqual = $isEqual && in_array($role, $user->getRoles());
}
}
return $isEqual;
}
return false;
}
The code above refreshes the User object if any new roles are added. The same principle also holds true for other fields you compare.
$user = $this->getUser();
$userManager = $this->get('fos_user.user_manager');
$user->addRole('ROLE_TEACHER');
$userManager->updateUser($user);
$newtoken = new \Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken($user,null,'main', $user->getRoles());
$token = $this->get('security.token_storage')->setToken($newtoken);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With