首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Symfony2中实现角色/资源ACL

如何在Symfony2中实现角色/资源ACL
EN

Stack Overflow用户
提问于 2013-01-07 10:56:58
回答 2查看 1.1K关注 0票数 6

我对在Symfony2中实现访问控制列表的方式感到有点不安。

在Zend (版本1& 2)中,定义了资源列表和角色列表,并为每个角色分配了允许访问的资源子集。因此,资源和角色是ACL实现的主要词汇表,在Symfony2中不是这样,因为只有角色才是规则。

在遗留应用数据库中,我有定义角色列表、资源列表和每个角色允许的资源列表(多到多关系)的表。每个用户都被分配一个角色(管理员、超级管理员、编辑器等等)。

我需要在Symfony2应用程序中使用这个数据库。我的资源看起来如下: ARTICLE_EDIT、ARTICLE_WRITE、COMMENT_EDIT等等。

我在Symfony中的User实体实现了Symfony\Component\Security\Core\User\UserInterface接口,因此有一个getRoles)方法。

我打算使用这个方法来定义允许的资源,这意味着我使用角色作为资源(我的意思是Zend Framework中的所谓资源在这里被称为角色)。

你确认我应该用这种方法吗?

这意味着我不再关心这个角色(管理员,编辑,.)对每个用户,但只对其资源。

然后,我将在控制器中使用$this->get('security.context')->isGranted('ROLE_ARTICLE_WRITE')

这是正确的做法吗?在Symfony中使用角色不是一种规避的方式吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-27 15:26:54

几年后,要回答这个问题,是很容易解决的。

解决办法是混合角色和资源的概念。

假设定义了role表、resource表和role_resource多到多关系。

用户存储在user表中。

以下是相应的原则实体:

用户:

代码语言:javascript
运行
复制
use Symfony\Component\Security\Core\User\UserInterface;

class User implements UserInterface
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    private $id;

    /**
     * @ManyToOne(targetEntity="Role")
     * @JoinColumn(name="role_id", referencedColumnName="id")
     **/
    private $role;

    // ...
}

角色:

代码语言:javascript
运行
复制
class Role
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    private $id;

    /** @Column(type="string") */
    private $name;

    /**
     * @ManyToMany(targetEntity="Resource")
     * @JoinTable(name="role_resource",
     *      joinColumns={@JoinColumn(name="role_id", referencedColumnName="id")},
     *      inverseJoinColumns={@JoinColumn(name="resource_id", referencedColumnName="id")}
     *      )
     **/
    private $resources;

    // ...
}

资源:

代码语言:javascript
运行
复制
class Resource
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    private $id;

    /** @Column(type="string") */
    private $name;

    // ...
}

因此,现在的解决方案是以这种方式实现getRoles of UserInterface

代码语言:javascript
运行
复制
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Role\Role;

class User implements UserInterface
{
    // ...

    /**
     * @var Role[]
     **/
    private $roles;

    /**
     * {@inheritDoc}
     */
    public function getRoles()
    {
        if (isset($this->roles)) {
            return $this->roles;
        }

        $this->roles = array();

        $userRole = $this->getRole();

        $resources = $userRole->getResources();

        foreach ($resources as $resource) {
            $this->roles[] = new Role('ROLE_' . $resource);
        }

        return $this->roles;
    }

}

这样,就可以以这种方式检查赋予当前用户的资源(考虑到有一个名为ARTICLE_WRITE的资源):

代码语言:javascript
运行
复制
$this->get('security.context')->isGranted('ROLE_ARTICLE_WRITE')
票数 2
EN

Stack Overflow用户

发布于 2014-10-04 14:01:47

我想这会回答你的问题。

http://symfony.com/doc/current/cookbook/security/acl.html advanced.html

代码语言:javascript
运行
复制
$builder = new MaskBuilder();
$builder
->add('view')
->add('edit')
->add('delete')
->add('undelete');
$mask = $builder->get(); // int(29)

$identity = new UserSecurityIdentity('johannes', 'Acme\UserBundle\Entity\User');
$acl->insertObjectAce($identity, $mask);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14194460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档