I've faced with problem trying to implement simple autorization system in SF4.
class User implements UserInterface {
// some properties...
/**
* @var RoleGroup|null
* @ORM\ManyToOne(targetEntity="App\Entity\RoleGroup")
* @ORM\JoinColumn(nullable=true)
*/
private $roleGroup;
/** method imposed by built-in UserInterface (SF4) **/
public function getRoles(): array {
if(null === $this->roleGroup) return ['ROLE_DEFAULT'];
/** returns an array of role names **/
return $this->roleGroup->getRoles();
}
}
UserProvider:
class UserProvider implements UserProvider
{
public function refreshUser(UserInterface $user)
{
$qb = $this->createQueryBuilder('u');
$qb->select('u, r');
$qb->leftJoin('u.roleGroup', 'r');
$qb->where($qb->expr()->eq('u.id', $user->getId()));
return $qb->getQuery()->getOneOrNullResult();
}
}
Steps symfony follows:
- Authentication: after success: The user object is serialized to session (whole, by default), roles are stored separately
- Refresh user: Security component triggers UserProviderInterface::refreshUser(UserInterface $user) method, coompares them and if objects are not equal it de-authenticates the user (according to documentation)
It's clear and easy to understand, but:
- Why is the result of an UserInterface::getRoles() separated?
- Why doesn't SF4 get roles from the serialized User object?
- Why roles are placed into the session ONCE (after successful authentication)?
- Why aren't the roles refreshed if an UserProvider refreshes an user every request (by default)?
- Why doesn't always_authenticate_before_granting => true refresh the user's roles?
Problem: I would like to refresh the user's roles on every request. I am aware I can get rid of the problem via a listener that will refresh token every request, but is there any diffrent solotion?