как программно назначить роль пользователю symfony4

Я пытаюсь создать маршрут для программного назначения определенной РОЛИ текущему пользователю. Это моя попытка.

/**
 * @Route("/role/assign/{role}", name="role_assignment")
 */
public function assign($role)
{
    $session = $this->get('session');
    $firewallContext = 'main';
    $token = new UsernamePasswordToken(
        'admin',
        null,
        $firewallContext,
        array('ROLE_ADMIN')
    );
    $session->set('_security_'.$firewallContext, serialize($token));
    $session->save();
    $cookie = new Cookie($session->getName(), $session->getId());

    $response = new JsonResponse([
        'success' => 'true',
        'user' => $this->getUser(),
    ]);

    $response->headers->setCookie($cookie);

    return $response;
}

Пользователь всегда нулевой, но я ожидал, что он станет «админом» после обновления страницы.


person sensorario    schedule 06.04.2018    source источник


Ответы (1)


Я бы настоятельно рекомендовал вам не делать такие вещи на производственных платформах. Лучше правильно настроить имперсонацию пользователя. Это избавит вас от головной боли, связанной с необходимостью делать все это вручную.

Если вы действительно, действительно, хотите пойти по этому пути, попробуйте следующий код:

/**
 * @Route("/role/assign/{username}/{role}", name="role_assignment")
 *
 * @param \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface $tokenStorage
 *
 * @return JsonResponse
 */
public function assign($username, $role, TokenStorageInterface $tokenStorage)
{
    // NOTES:
    //  1. Make sure you are using the same User class as the one configured in `security.yml`
    //  2. Keep in mind the $username MUST exist and MUST have the role you are setting,
    //     because the UserPasswordToken is reloaded from the session upon page refresh which triggers a check in the user provider and that will hit the database. In other words, if the user doesn't have `ROLE_ADMIN` you will most-likely get logged out or see "AccessDeniedException".
    //     For more information check \Symfony\Component\Security\Core\User\UserProviderInterface::refreshUser.
    $user = new \Symfony\Component\Security\Core\User\User($username, null, array($role), true);

    // Create token
    $firewall = 'main'; // This  MUST MATCH the name in your security.firewalls.->main<- or authentication WILL FAIL!
    $usernamePasswordToken = new UsernamePasswordToken($user, null, $firewall, $user->getRoles());

    // You don't need to save the token via $session->save().
    // You can directly use $tokenStorage, which will do that for you.
    $tokenStorage->setToken($usernamePasswordToken);

    // Pass authentication to client.
    return new JsonResponse(['success' => 'true', 'user' => $user]);
}

Если вы пытаетесь пройти аутентификацию для тестовых случаев, вы можете посмотреть мой ответ здесь, который показывает, как вы можете настроить client, который может аутентифицироваться как любой пользователь с любой установленной вами ролью (пользователь даже не должен существовать в базе данных). У меня это отлично работает на 3.4, так что должно работать и на 4.0.

person tftd    schedule 07.04.2018