2013-01-07 13 views
6

Ich bin etwas beunruhigt darüber, wie die Zugriffskontrolllisten in Symfony2 implementiert sind.So implementieren Sie die Rollen-/Ressourcen-ACL in Symfony2

In Zend Framework (Version 1 & 2), eine Liste der Ressourcen und eine Liste der Rollen definiert sind und jede Rolle eine Teilmenge der Ressourcen zugewiesen ist es für den Zugriff erlaubt ist. Ressourcen und Rollen sind daher das Hauptvokabular der ACL-Implementierung, was in Symfony2, wo nur Rollen regieren, nicht der Fall ist.

In einer Legacy-App-Datenbank habe ich Tabellen, die eine Liste von Rollen, eine Liste von Ressourcen und eine Liste zulässiger Ressourcen für jede Rolle definieren (Viele-zu-Viele-Beziehung). Jedem Benutzer ist eine Rolle zugewiesen (Admin, Super Admin, Editor usw.).

Ich muss diese Datenbank in einer Symfony2-Anwendung verwenden. Meine Ressourcen wie folgt aussehen: ARTICLE_EDIT, ARTICLE_WRITE, COMMENT_EDIT usw.

Meine User Einheit in Symfony implementiert die Symfony\Component\Security\Core\User\UserInterface Schnittstelle und hat daher eine getRoles) Methode.

Ich beabsichtige, diese Methode zu verwenden, um die erlaubten Ressourcen zu definieren, was bedeutet, dass ich Rollen als Ressourcen verwende (ich meine, dass das, was in Zend Framework Ressourcen genannt wird, hier Rollen genannt wird).

Bestätigen Sie, dass ich diese Methode verwenden soll?

Das bedeutet, dass ich mich nicht mehr um die Rolle (Admin, Editor, ...) jedes Benutzers kümmere, sondern nur um seine Ressourcen.

Ich würde dann $this->get('security.context')->isGranted('ROLE_ARTICLE_WRITE') in meinen Controllern verwenden.

Ist dies der richtige Weg und wäre es keine umgangene Möglichkeit, Rollen in Symfony zu verwenden?

Antwort

2

diese Frage Jahre später zu beantworten, war es recht einfach zu lösen.

Die Lösung besteht darin, die Begriffe von Rollen und Ressourcen zu mischen.

Angenommen, eine role Tabelle, eine resource Tabelle und und role_resource viele zu viele Beziehung definiert sind.

Benutzer werden in einer user Tabelle gespeichert.

Hier sind die entsprechenden Lehre Einheiten:

Benutzer:

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; 

    // ... 
} 

Rolle:

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; 

    // ... 
} 

Ressource:

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

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

    // ... 
} 

So, jetzt ist die Lösung zur Umsetzung des getRoles von UserInterface auf diese Weise:

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

} 

Auf diese Weise auf den aktuellen Benutzer zugeschrieben Ressourcen können auf diese Weise überprüft werden (unter Berücksichtigung der dort eine Ressource, deren Name ist ARTICLE_WRITE):

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