Сервер OAuth2 с внешним источником пользователя

Я создаю сервер OAuth2 с большим FOSOAuthServerBundle.

Мое приложение Symfony аутентифицирует пользователей, приходящих из другого источника (фактически с другого сервера).

Я создал кастом UserProvider который отлично работает со стандартным уровнем безопасности Symfony. У меня есть моя реализация UserInterface но это, очевидно, не сущность базы данных.

Реализация классов для AccessToken, RefreshToken & AuthCode как сказано в инструкции по установке для доктрины я определил ссылку на пользователя как

//...
/**
* @ORM\Column(type="integer")
*/
protected $user_id;
//...

Кажется ли это логичным, пока нет?

Теперь истинный вопрос:
Где я могу указать способ привязки моих пользователей к различным токенам?


Я также был задавать вопрос на официальном репо для наглядности

1

Решение

Я сделал 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 }

Пользовательский объект теперь всегда должен быть присоединен к токенам

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]