Symfony 获取用户角色
我有Entities User implements UserInterface,它与实体角色implements RoleInterface有多对多关系 我的项目在登录后需要角色_ADMIN,否则将返回AccessDenied错误。 此外,我在数据库的ROLE表中添加了一个ROLE\u ADMIN角色,并在User\u Roles多对多表中创建了一个与此角色相关的用户 但是当我登录时,我总是会收到AccessDenied错误 当我在User中更改getRoles方法以返回数组'ROLE_ADMIN';它起作用了 有什么想法吗 我还必须在User中添加此方法,否则我无法在数据库中添加用户Symfony 获取用户角色,symfony,roles,Symfony,Roles,我有Entities User implements UserInterface,它与实体角色implements RoleInterface有多对多关系 我的项目在登录后需要角色_ADMIN,否则将返回AccessDenied错误。 此外,我在数据库的ROLE表中添加了一个ROLE\u ADMIN角色,并在User\u Roles多对多表中创建了一个与此角色相关的用户 但是当我登录时,我总是会收到AccessDenied错误 当我在User中更改getRoles方法以返回数组'ROLE_ADM
public function setUserRoles($userRoles)
{
if ( is_array($userRoles) ) {
$this->userRoles = $userRoles ;
} else {
$this->userRoles->clear() ;
$this->userRoles->add($userRoles) ;
}
return $this;
}
用户:
角色:
Security.yml
jms_security_extra:
secure_all_services: false
expressions: true
security:
encoders:
Acme\AppBundle\Entity\User: sha512
Symfony\Component\Security\Core\User\User: plaintext
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
chain_providers:
chain:
providers: [main, in_memory]
main:
entity: { class: Acme\AppBundle\Entity\User, property: username }
in_memory:
memory:
users:
user: { password: userpass, roles: [ 'ROLE_USER' ] }
admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
firewalls:
secured_area:
pattern: .*
form_login: ~
logout: ~
anonymous: ~
#http_basic:
# realm: "Secured Demo Area"
#access_control:
#- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
用户存储库:
namespace Acme\AppBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException;
class UserRepository extends EntityRepository implements UserProviderInterface
{
public function loadUserByUsername($username)
{
$q = $this
->createQueryBuilder('u')
->select('u, r')
->leftJoin('u.userRoles', 'r')
->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();
} catch (NoResultException $e) {
$message = sprintf(
'Unable to find an active admin AcmeUserBundle:User object identified by "%s".',
$username
);
throw new UsernameNotFoundException($message, 0, $e);
}
return $user;
}
...
}
测试:
请确保UserRepository中的loadUserByUsername正确加入用户实体上的相应角色,并且角色实体上的User->getRoles和Role->getRole返回正确的数组/字符串
例如,您可以在TestController中通过手动查询UserRepository::loadUserByUsername方法来测试这一点,并检查角色是否存在
下一个可能是延迟加载问题。尝试:
/**
* @ORM\ManyToMany(targetEntity="Role", inversedBy="users", fetch="EAGER")
* @ORM\JoinTable(name="user_roles")
*
*/
private $userRoles;
文件说:
从自定义实体提供程序检索用户时,提高性能并避免延迟加载组
如果这不是您的问题的解决方案,请发表评论,无论如何,通过快速加载获取用户组或用户角色关系是一个很好的做法
请记住在更改提取设置后清除缓存
提示:
关于你的addRole方法。。。您很可能不想多次向用户添加角色实体,但前提是尚未添加角色实体。最好这样写:
public function addRole(RoleInterface $role)
{
if (!$this->roles->contains($role)) {
$this->roles->add($role);
}
return $this;
}
请确保UserRepository中的loadUserByUsername正确加入用户实体上的相应角色,并且角色实体上的User->getRoles和Role->getRole返回正确的数组/字符串
例如,您可以在TestController中通过手动查询UserRepository::loadUserByUsername方法来测试这一点,并检查角色是否存在
下一个可能是延迟加载问题。尝试:
/**
* @ORM\ManyToMany(targetEntity="Role", inversedBy="users", fetch="EAGER")
* @ORM\JoinTable(name="user_roles")
*
*/
private $userRoles;
文件说:
从自定义实体提供程序检索用户时,提高性能并避免延迟加载组
如果这不是您的问题的解决方案,请发表评论,无论如何,通过快速加载获取用户组或用户角色关系是一个很好的做法
请记住在更改提取设置后清除缓存
提示:
关于你的addRole方法。。。您很可能不想多次向用户添加角色实体,但前提是尚未添加角色实体。最好这样写:
public function addRole(RoleInterface $role)
{
if (!$this->roles->contains($role)) {
$this->roles->add($role);
}
return $this;
}
谢谢你的回答。我尝试了fetch=Eager,但仍然存在令牌没有所需角色的问题。错误消息。在app_dev.php分析器中,用户经过身份验证,但角色:[null]更新了我的答案-请提供您的UserRepository::loadUserByUsername方法。。也许是QueryBuilder的问题。我想我有你的解决方案。。。请查看我的更新答案!还添加了一个提示。您好,我在我的存储库中检查了loadByUsername方法,并在第一篇文章的末尾提供了我的存储库。我找不到任何错误。我正在尝试测试我的loadByUsername。找不到我的错误。当我测试loadUserByUsername方法并且在loadUserByUsername方法之后执行类似操作时:$test=$users->getRoles;打印$test[0],然后不显示任何内容。没有数组输入。打印$test[0];谢谢你的回答。我尝试了fetch=Eager,但仍然存在令牌没有所需角色的问题。错误消息。在app_dev.php分析器中,用户经过身份验证,但角色:[null]更新了我的答案-请提供您的UserRepository::loadUserByUsername方法。。也许是QueryBuilder的问题。我想我有你的解决方案。。。请查看我的更新答案!还添加了一个提示。您好,我在我的存储库中检查了loadByUsername方法,并在第一篇文章的末尾提供了我的存储库。我找不到任何错误。我正在尝试测试我的loadByUsername。找不到我的错误。当我测试loadUserByUsername方法并且在loadUserByUsername方法之后执行类似操作时:$test=$users->getRoles;打印$test[0],然后不显示任何内容。没有数组输入。打印$test[0];请从问题中删除实体中与角色无关的内容。只留下方法-问题很长,就像这样。我根据您的代码稍微更改了我的实体。。我在用户角色方面遇到问题..:-现在已经修好了。。顺便说一句,您应该使用dto并在实体外部实现高级用户界面。。。由于您的安全性不应了解实体,因此要将其解耦。请从问题中删除实体中与角色无关的内容。乐
只保留方法-问题很长,就像这样。我根据您的代码稍微更改了我的实体。。我在用户角色方面遇到问题..:-现在已经修好了。。顺便说一句,您应该使用dto并在实体外部实现高级用户界面。。。将其解耦,因为您的安全性不应了解实体。
public function addRole(RoleInterface $role)
{
if (!$this->roles->contains($role)) {
$this->roles->add($role);
}
return $this;
}