我有一个应用程序可以管理一个实体(USER)内的所有用户,并根据建议实施UserInterface
。
链接到它,我得到了CUSTOMER和EMPLOYEE实体:每个实体都存储有关用户的特定信息。
您可能会问我为什么要这样做:员工可以在许多工作场所担任客户,并且可以在许多工作场所工作。为了避免重复,常用信息集中在USER中,而USER中的属性Roles
在db中始终为空。
这里的目标是在EMPLOYEE登录时根据存储在另一个实体(WORKPLACE)中的特定数据加载我的角色。
我的大问题可能存在于UserRepository
中:当symfony调用存储库以查找在登录表单上输入的用户时,主义不提供任何角色。我摆上了角色,并将User
返回给Authenticator(香草的,我还没有碰过)。每次重新查询结束后,Symfony都会检查用户,但然后说教义会加载ROLE_CLIENT
(换句话说,没有特权)。
我已经尝试过的事情失败了
UserLoaderInterface
UserRepository
(如此处https://symfony.com/doc/master/security/user_provider.html#using-a-custom-query-to-load-the-user所示)实体
class User implements UserInterface
{
/**
* @ORM\Id()
*/
private $cpf;
/**
* @ORM\Column
*
*/
private $email;
/**
* @ORM\Column
*/
private $nome;
/**
* @var string
*
* @ORM\Column
*/
private $telefone;
/**
* @var \DateTime|null
*
* @ORM\Column
*/
private $nascimento;
/**
* @var \DateTime|null
*
* @ORM\Column
*/
private $ultimoLogin;
/**
* @var string|null
*
* @ORM\Column
*/
private $endereco;
/**
* @var string|null
*
* @ORM\Column
*/
private $cidade;
/**
* @var string|null
*
* @ORM\Column
*/
private $uf;
/**
* @var int|null
*
* @ORM\Column
*/
private $cep;
/**
* @ORM\Column(name="Roles", type="json")
*/
private $roles = [];
/**
* @var string The hashed password
* @ORM\Column(name="password", type="string")
*/
private $password;
//vanilla getters and setters
工作场所实体
布尔值存储我想获得的特权
class LocalTrabalho
{
/**
* @var Configuracao
*
* @ORM\ManyToOne(targetEntity=Configuracao::class, inversedBy="localTrabalho")
* @ORM\JoinColumn(name="CNPJ", referencedColumnName="CNPJ", nullable=false)
* @ORM\Id
* the company unique code
*/
private $cnpj;
/**
* @var Funcionario
*
* @ORM\ManyToOne(targetEntity=Funcionario::class, inversedBy="localTrabalho")
* @ORM\JoinColumn(name="CPF_Funcionario", referencedColumnName="CPF", nullable=false)
* @ORM\Id
* the user-employee unique code
*/
private $cpfFuncionario;
/**
* @var bool
*
* @ORM\Column
* is this employee is active?
*/
private $ativo = 1;
/**
* @var bool
*
* @ORM\Column
*/
private $privilegioCaixa = 0;
/**
* @var bool
*
* @ORM\Column
*/
private $privilegioPrestador = 1;
/**
* @var bool
*
* @ORM\Column
*/
private $privilegioRecepcao = 0;
/**
* @var bool
*
* @ORM\Column
*/
private $privilegioAdministracao = 0;
员工实体
class Funcionario
{
/**
* @var int
*
* @ORM\Column
* @ORM\Id
* @ORM\GeneratedValue(strategy="NONE")
*/
private $cpf;
/**
* @var string|null
*
* @ORM\Column
*/
private $ctps;
/**
* @var string|null
*
* @ORM\Column
*/
private $foto;
来自db的USER元组示例
# CodPFis, email, password, Roles, Nome, Telefone, Nascimento, Ultimo_login, Endereco, Cidade, UF, CEP
'89038252099', 'sophiejenniferteresinhaoliveira__sophiejenniferteresinhaoliveira@grupomozue.com.br', '$argon2id$v=19$m=65536,t=4,p=1$WEn7b64I9744kRJICEpaLA$jcYLDvh2bZsZPakMDGsncpbfIZwR6lN0QcgJOOSerK0', NULL, 'João da Silva', '', NULL, NULL, NULL, NULL, NULL, NULL
我的最后一个资源是在这里,在漫长而浪费的工作时间后,我该怎么办(或我做错了什么)?
我已经看到其他一些线程在问类似的问题,但是它们已经过时了(使用版本5): Dynamic roles in symfony Symfony 2 - Loading roles from database Symfony2 - Dynamic Role Management How to update roles in security token in Symfony 4 without re-logging in Symfony User Logout After Role Change
PS:有人尝试过这种方法(https://github.com/symfony/symfony/issues/12025#issuecomment-562004005)并在symfony5中获得成功吗?
答案 0 :(得分:0)
嗯,事实证明,对于我的案例来说,最好的解决方案是操作 User
存储库。 Doctrine 使用它们来操作数据库,所以我只是在里面编写了我的规则,让框架来完成剩下的工作。
算法如下图所示:
$id
ROLE
常量加载到 User
实体中public function find($id, $lockmode=null, $lockversion = null){
$us = $this->createQueryBuilder('u')
->andWhere('u.cpf = :cpf')
->setParameter('cpf', $id['cpf'])
->getQuery()->getOneOrNullResult();
$lt = $this->_em->createQuery(
'SELECT t
FROM App\Entity\LocalTrabalho t
WHERE t.cpfFuncionario = :cpf'
)
->setParameters(['cpf' => $us->getCpf()])
->getResult();
if (count($lt) > 0){
$regras = ['ROLE_FUNCIONARIO'];
if ($lt[0]->getPrivilegioCaixa()) $regras[] = 'ROLE_CAIXA';
if ($lt[0]->getPrivilegioPrestador()) $regras[] = 'ROLE_PRESTADOR';
if ($lt[0]->getPrivilegioRecepcao()) $regras[] = 'ROLE_RECEPCAO';
if ($lt[0]->getPrivilegioAdministracao())
{
$regras = ['ROLE_ADMIN'];
}
$us->setRoles($regras);
}
return $us;
}