我正在使用优秀的FOSOAuthServer捆绑包构建OAuth2服务器。
我的Symfony应用程序验证来自其他来源(实际上是另一台服务器)的用户。
我创建了一个自定义UserProvider
,可以使用默认的Symfony安全层。我有UserInterface
的实现,但它显然不是数据库的实体。
实施AccessToken
,RefreshToken
&的课程对于Doctrine,AuthCode
为told in the installation instructions,我将用户引用定义为
//...
/**
* @ORM\Column(type="integer")
*/
protected $user_id;
//...
在那之前它似乎合乎逻辑吗?
现在真正的问题是: 在哪里指定将用户链接到不同令牌的方式?
出于可见度目的,我还在asking the question官方回购
答案 0 :(得分:1)
我最终做了两件事:
user
LifecycleEvent
侦听器首先扩展令牌类(例如使用Trait)
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 }
现在,用户对象应始终附加到令牌