Symfony 2 - 从数据库加载角色 [英] Symfony 2 - Loading roles from database

查看:42
本文介绍了Symfony 2 - 从数据库加载角色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的角色存储在数据库中,我尝试在登录时动态加载它们.我正在做的是查询角色并将它们设置在我的用户提供程序中的用户对象上,如下所示:

My roles are stored in the database and I am trying to load them dynamically upon login. What I'm doing is querying for the roles and setting them on the user object in my user provider as seen here:

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 works fine and dandy and I see the correct roles when I do:

$this->get('security.context')->getUser()->getRoles()

问题(我认为)是令牌不知道这些角色.因为在令牌上调用 getRoles() 仅显示 ROLE_USER,这是默认角色.

The problem (I think), is that the token does not know about these roles. Because calling getRoles() on the token is showing only ROLE_USER, which is the default role.

在我看来,令牌是在 UserProvider 加载用户之前创建的.我已经查看了很多安全组件,但我终其一生都找不到流程的正确部分来挂钩以正确设置这些角色,以便令牌了解它们.

It seems to me that the token is being created before the user is loaded by the UserProvider. I've looked through a lot of the security component but I can't for the life of me find the right part of the process to hook into to set these roles correctly so that the token knows about them.

更新 按照从数据库文档加载角色工作正常,但这与我的用例不匹配,如下所示.我的架构不同,因为每个角色都有额外的权限(查看/添加/编辑/删除),这就是我在这里尝试这种方法的原因.我不想仅仅为了使用 Symfony 的安全性而改变我的模式.我宁愿理解为什么此时这些角色没有正确绑定到我的用户对象上(不确定这里的教义词是否正确).

Update Following the Load roles from database doc works fine, but this does not match my use case as shown here. My schema differs as each role has additional permissions (view/add/edit/delete) and this is why I am attempting the approach here. I don't want to have to alter my schema just to work with Symfony's security. I'd rather understand why these roles are not properly bound (not sure the correct doctrine word here) on my user object at this point.

推荐答案

这里的问题源于我以为我正在实施

The problem here stemmed from the fact that I thought I was implementing

Symfony\Component\Security\Core\User\EquatableInterface;

但不是(正如您在原始问题中所见,我忘记将其添加到我的类定义中).如果人们遇到它,我会把它留在这里给人们.您只需要实现此接口,并将以下方法添加到您的用户实体中即可.

but wasn't (as you can see in the original question, I forgot to add it to my class definition). I'm leaving this here for people if they come across it. All you need is to implement this interface, and add the following method to your user entity.

public function isEqualTo(UserInterface $user) {
    if ($user instanceof User) {
    // Check that the roles are the same, in any order
        $isEqual = count($this->getRoles()) == count($user->getRoles());
        if ($isEqual) {
            foreach($this->getRoles() as $role) {
                $isEqual = $isEqual && in_array($role, $user->getRoles());
            }
        }
        return $isEqual;
    }

    return false;
}

这篇关于Symfony 2 - 从数据库加载角色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆