Я создаю сервер OAuth2 с большим FOSOAuthServerBundle.
Мое приложение Symfony аутентифицирует пользователей, приходящих из другого источника (фактически с другого сервера).
Я создал кастом UserProvider
который отлично работает со стандартным уровнем безопасности Symfony. У меня есть моя реализация UserInterface
но это, очевидно, не сущность базы данных.
Реализация классов для AccessToken
, RefreshToken
& AuthCode
как сказано в инструкции по установке для доктрины я определил ссылку на пользователя как
//...
/**
* @ORM\Column(type="integer")
*/
protected $user_id;
//...
Кажется ли это логичным, пока нет?
Теперь истинный вопрос:
Где я могу указать способ привязки моих пользователей к различным токенам?
Я также был задавать вопрос на официальном репо для наглядности
Я сделал 2 вещи:
user
LifecycleEvent
слушательСначала расширьте классы токенов (например, Черта характера)
namespace AppBundle\Entity;
use AppBundle\Security\User;
use Symfony\Component\Security\Core\User\UserInterface;
trait AppTokenTrait
{
/**
* @ORM\Column(type="string")
* @var string
*/
protected $username;
public function setUser(UserInterface $user)
{
if (!$user instanceof User) {
throw new \InvalidArgumentException(
sprintf("User must be an instance of %s", User::class)
);
}
$this->username = $user->getUsername();
$this->user = $user;
}
public function getUser()
{
if (!$this->user) {
throw new \RuntimeException(
"Unable to get user - user was not loaded by postLoad");
}
return $this->user;
}
/**
* @return string
*/
public function getUsername()
{
return $this->username;
}
}
В 3 классах токенов (и не забудьте обновить схему базы данных):
//...
use AppTokenTrait;
//...
Создать слушателя
namespace AppBundle\Services;
use AppBundle\Entity\AccessToken;
use AppBundle\Entity\AuthCode;
use AppBundle\Entity\RefreshToken;
use AppBundle\Security\UserProvider;
use Doctrine\ORM\Event\LifecycleEventArgs;
class AppTokenListener
{
/**
* @var UserProvider
*/
protected $userProvider;
public function __construct(UserProvider $userProvider)
{
$this->userProvider = $userProvider;
}
public function postLoad(LifecycleEventArgs $event)
{
$object = $event->getObject();
if (
$object instanceof AccessToken or
$object instanceof AuthCode or
$object instanceof RefreshToken
) {
$user = $this->userProvider->loadUserByUsername($object->getUsername());
$object->setUser($user);
}
}
}
Зарегистрируйте это как услугу
app.token.listener:
class: AppBundle\Services\AppTokenListener
tags:
- { name: doctrine.event_listener, event: postLoad }
Пользовательский объект теперь всегда должен быть присоединен к токенам
Других решений пока нет …