【发布时间】:2014-01-08 20:20:38
【问题描述】:
我的角色存储在数据库中,我尝试在登录时动态加载它们。我正在做的是查询角色并将它们设置在我的用户提供程序中的用户对象上,如下所示:
public function loadUserByUsername($username) {
$q = $this
->createQueryBuilder('u')
->where('u.username = :username')
->setParameter('username', $username)
->getQuery()
;
try {
// The Query::getSingleResult() method throws an exception
// if there is no record matching the criteria.
$user = $q->getSingleResult();
// Permissions
$permissions = $this->_em->getRepository('E:ModulePermission')->getPermissionsForUser($user);
if ($permissions !== null) {
foreach ($permissions as $permission) {
$name = strtoupper(str_replace(" ", "_", $permission['name']));
$role = "ROLE_%s_%s";
if ($permission['view']) {
$user->addRole(sprintf($role, $name, 'VIEW'));
}
if ($permission['add']) {
$user->addRole(sprintf($role, $name, 'ADD'));
}
if ($permission['edit']) {
$user->addRole(sprintf($role, $name, 'EDIT'));
}
if ($permission['delete']) {
$user->addRole(sprintf($role, $name, 'DELETE'));
}
}
}
} catch (NoResultException $e) {
throw new UsernameNotFoundException(sprintf('Unable to find an active admin Entity:User object identified by "%s".', $username), null, 0, $e);
}
return $user;
}
还有用户实体:
class User implements AdvancedUserInterface, \Serializable {
....
protected $roles;
....
public function __construct() {
$this->salt = base_convert(sha1(uniqid(mt_rand(), true)), 16, 36);
$this->roles = array();
}
....
public function getRoles() {
$roles = $this->roles;
// Ensure we having something
$roles[] = static::ROLE_DEFAULT;
return array_unique($roles);
}
public function addRole($role) {
$role = strtoupper($role);
$roles = $this->getRoles();
if ($role === static::ROLE_DEFAULT) {
return $this;
}
if (!in_array($role, $roles, true)) {
$this->roles[] = $role;
}
return $this;
}
public function hasRole($role) {
$role = strtoupper($role);
$roles = $this->getRoles();
return in_array($role, $roles, true);
}
}
这很好用,而且我看到了正确的角色:
$this->get('security.context')->getUser()->getRoles()
问题(我认为)是令牌不知道这些角色。因为在令牌上调用 getRoles() 只显示 ROLE_USER,这是默认角色。
在我看来,令牌是在 UserProvider 加载用户之前创建的。我已经查看了很多安全组件,但我一生都无法找到正确的流程部分来正确设置这些角色,以便令牌了解它们。
更新遵循从数据库文档加载角色可以正常工作,但这与我的用例不匹配,如此处所示。我的架构不同,因为每个角色都有额外的权限(查看/添加/编辑/删除),这就是我在这里尝试这种方法的原因。我不想仅仅为了使用 Symfony 的安全性而改变我的模式。我宁愿理解为什么这些角色此时没有正确绑定到我的用户对象上(这里不确定正确的教义词)。
【问题讨论】: