Symfony 获取用户角色

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

我有Entities User implements UserInterface,它与实体角色implements RoleInterface有多对多关系

我的项目在登录后需要角色_ADMIN,否则将返回AccessDenied错误。 此外,我在数据库的ROLE表中添加了一个ROLE\u ADMIN角色,并在User\u Roles多对多表中创建了一个与此角色相关的用户

但是当我登录时,我总是会收到AccessDenied错误

当我在User中更改getRoles方法以返回数组'ROLE_ADMIN';它起作用了

有什么想法吗

我还必须在User中添加此方法,否则我无法在数据库中添加用户

  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;
}