使用组(具有角色)和具有撤消角色的用户创建登录 - Symfony2

时间:2013-06-14 23:24:42

标签: authentication symfony doctrine-orm

我在那里, 我想创建一个自定义身份验证,提供用户角色,组和角色组。我要创建的登录名是下一个:

用户拥有组和组具有角色;

用户有角色。此角色用于从组中撤消角色。

即:

Groups:
    Group1: ROLE_WRITE, ROLE_READ
    Group2: ROLE_CHECK, ROLE_NEW
Users:
    Groups:
        Group1
        Group2
    Roles
        ROLE_CHECK

通过上面的示例,用户只能使用3个角色ROLE_WRITE,ROLE_READ和ROLE_NEW

我做了以下课程

Roles.php

namespace Test\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\Role\RoleInterface;


/**
 * Test\OverSkyBundle\Entity\Roles
 *
 * @ORM\Table(name="roles")
 * @ORM\Entity()
 */

class Roles implements RoleInterface{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=70, unique=true)
     */
    private $role;

    public function __construct( $role )
    {
        $this->role = $role;
    }

    public function getId(){
        return $this->id;
    }

    public function getRole(){
        return $this->role;
    }
    public function setRole($role){
        $this->role = $role;
    }

    public function __toString()
    {
        return (string) $this->role;
    } 
}

Groups.php

namespace Test\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Test\OverSkyBundle\Entity\Groups
 *
 * @ORM\Table(name="groups")
 * @ORM\Entity()
 */

class Groups {

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=70, unique=true)
     */
    private $groupname;

    /**
     * @ORM\ManyToMany(targetEntity="Roles")
     *
     */
    private $roles;

    public function __construct()
    {
        $this->roles = new ArrayCollection();
    }

    public function __toString()
    {
        return $this->groupname;
    } 

    public function getId(){
        return $this->id;
    }

    public function getRoles()
    {
        return $this->roles->toArray();
    }
    public function setRoles($roles)
    {
        $this->roles = $roles;
    }
}

Users.php

<?php

namespace Test\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\Common\Collections\ArrayCollection;

/** 
* Test\OverSkyBundle\Entity\Users
 *
 * @ORM\Table(name="users")
 * @ORM\Entity(repositoryClass="Test\UserBundle\Entity\UsersRepository")
 */

class Users implements UserInterface, \Serializable{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=25, unique=true)
     */
    private $username;

    /**
     * @ORM\ManyToMany(targetEntity="Roles")
     *
     */
    private $roles;

    /**
     * @ORM\ManyToMany(targetEntity="Groups")
     *
     */
    private $groups;

    /**
     * @ORM\Column(type="string", length=32)
     */
    private $salt;

    /**
     * @ORM\Column(type="string", length=140)
     */
    private $password;

    /**
     * @ORM\Column(type="string", length=140, unique=true)
     */
    private $email;

    /**
     * @ORM\Column(name="is_active", type="boolean")
     */
    private $isActive; 

    public function __toString()
    {
        return $this->name;
    } 

    public function __construct() {
        $this->roles = new ArrayCollection();
        $this->groups = new ArrayCollection();
        $this->isActive = true;
        $this->salt = md5(uniqid(null, true));
    }

    public function getId()
    {
        return $this->id;
    }

    public function getRoles()
    {
        return $this->roles->toArray();
    }
    public function setRoles($roles)
    {
        $this->roles = $roles;
    }

    public function getGroups()
    {
        return $this->groups->toArray();
    }
    public function setGroups($groups)
    {
        $this->groups = $groups;
    }    

    public function getUsername()
    {
        return $this->username;
    }
    public function setUsername($username)
    {
        $this->username = $username;
    }    

    public function getSalt()
    {
        return $this->salt;
    }
    public function setSalt($salt)
    {
        $this->salt = $salt;
        return $this;
    }

    public function getPassword()
    {
        return $this->password;
    }    
    public function setPassword($password)
    {
        $this->password = $password;
        return $this;
    }

    public function getEmail()
    {
        return $this->email;
    }
    public function setEmail($email)
    {
        $this->email = $email;
        return $this;
    }  

    public function getIsActive()
    {
        return $this->isActive;
    }  
    public function setIsActive($isActive)
    {
        $this->isActive = $isActive;
        return $this;
    }   

    public function eraseCredentials() {

    }

    public function serialize() {
        return serialize(array(
            $this->id,
        ));        
    }

    public function unserialize($serialized) {
        list (
            $this->id,
        ) = unserialize($serialized);
    }
}

index.html.twig

{% if is_granted('ROLE_ZAP') %}
    dasdsa
{% endif %}

{% for groups in app.user.groups %}    
    <li> groups </li>
{% endfor %}

在twig文件中,我可以访问用户角色,但不能访问组角色。如何将两者合并并撤销用户中存在的角色?

如果我尝试在app.user.groups.roles中执行群组,则会收到错误,指出找不到角色。

如果is_granted执行,我会收到用户角色。

1 个答案:

答案 0 :(得分:0)

is_granted()调用用户的 getRoles()方法,并检查给定的参数角色是否在返回的角色数组中。 (简化 - 安全提供程序调用getRoles并将它们添加到安全上下文中,然后is_granted检查安全上下文更精确)

现在,如果您想要返回从用户组继承的角色,则必须合并这些角色。

虽然我不知道你为什么试图撤销用户的角色来自群组提供的角色......

(通常是用户的角色扩展他们的群组提供的角色 - 如果您不想要某些角色,请不要将用户添加到群组中)

......你可以这样做:

Users.php

public function getRoles()
{
    $groupRoles = array();
    // add all roles provided by groups
    foreach ($this->getGroups() as $group) {
        foreach ($group->getRoles() as $role) {
            $groupRoles[] = $role;
        }
    }
    // - remove dublicates
    // - revoke user's roles
    // - return remaining roles
    return array_unique(array_diff($groupRoles, $this->getRoles()));
}