2013-01-07 1 views
6

나는 Symfony2에서 액세스 제어 목록을 구현하는 방법에 대해 약간 당황 스럽다.Symfony2에서 역할/리소스 ACL을 구현하는 방법

젠드 프레임 워크에서

(버전 1 & 2), 자원의 목록과 역할의 목록을 정의하고 각 역할은 자원의 부분 집합이 액세스가 허용있어 할당됩니다. 따라서 자원과 역할은 ACL 구현의 주된 어휘입니다. Symfony2에서는 역할 만 규칙입니다.

레거시 앱 데이터베이스에는 역할 목록, 리소스 목록 및 각 역할에 대해 허용 된 리소스 목록 (다 대다 관계)을 정의하는 테이블이 있습니다. 각 사용자에게는 역할 (관리자, 수퍼 관리자, 편집자 등)이 할당됩니다.

이 데이터베이스를 Symfony2 응용 프로그램에서 사용해야합니다. 내 자원은 다음과 같이 : 등 ARTICLE_EDIT, ARTICLE_WRITE, COMMENT_EDIT을

심포니 나의 User 기업은 Symfony\Component\Security\Core\User\UserInterface 인터페이스를 구현하고 따라서 getRoles) 방법이있다.

나는이 방법을 사용하여 허용 된 리소스를 정의하려고합니다. 즉, 저는 리소스를 역할로 사용한다는 의미입니다. 젠드 프레임 워크의 리소스를 여기서 역할이라고 부릅니다.

이 방법을 사용해야한다고 확인합니까?

이것은 각 사용자의 역할 (관리자, 편집자 등)에 대해 더 이상 신경 쓰지 않는다는 것을 의미합니다.

컨트롤러에 $this->get('security.context')->isGranted('ROLE_ARTICLE_WRITE')을 사용합니다.

이것은 올바른 방법이며 Symfony에서 역할을 사용하는 우회적 인 방법이 아니겠습니까?

답변

2

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

는 그것을 해결하기 매우 쉬웠다, 나중에이 질문 년에 대답합니다.

해결 방법은 역할과 자원의 개념을 혼합하는 것입니다.

role 테이블, resource 테이블 및 role_resource 많은 관계가 정의되어 있다고 가정 해 보겠습니다.

사용자는 user 테이블에 저장됩니다.여기

는 해당 교리의 엔티티 :

사용자 :

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; 

    // ... 
} 

역할 :

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; 

    // ... 
} 

리소스 :

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

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

    // ... 
} 

이제 솔루션이 구현하는 것입니다UserInterfacegetRoles 이러한 방식 :

$this->get('security.context')->isGranted('ROLE_ARTICLE_WRITE') 
:

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 리소스가 고려)

0

이 질문에 대한 답변을 드릴 것입니다. http://symfony.com/doc/current/cookbook/security/acl_advanced.html

$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); 
관련 문제