2012-08-28 7 views
5

Ich bin beschäftigt mit einer Symfony2-Anwendung, die einige ACL-Berechtigungen benötigt.Symfony2 ACL Zugriff auf mehrere Objekte für mehrere Benutzer

Ich bin ein Neuling mit Symfony2, also nicht sicher, ob ich das auf die richtige Weise ansehe.

Ich habe mehrere Clients mit jeweils mehreren Konten.

Ich habe ein Super-Administrator (ROLE_SUPER_ADMIN), die den Zugriff auf alle Clients und alle Konten haben. Dann habe ich eine Admin-Rolle (ROLE_ADMIN), die nur Zugriff auf einen bestimmten Client und alle Konten für diese Clients erlaubt wird. Dann gibt es Agenten (ROLE_AGENT), die nur bestimmte Konten für Clients haben sollten.

Ich sah auf den symfony-Dokumentation, die einem Benutzer den Zugriff auf ein bestimmtes Objekt zu geben, ich den folgenden Code verwenden:

// creating the ACL 
$aclProvider = $this->get('security.acl.provider'); 
$objectIdentity = ObjectIdentity::fromDomainObject($account); 
$acl = $aclProvider->createAcl($objectIdentity); 

// retrieving the security identity of the currently logged-in user 
$securityContext = $this->get('security.context'); 
$user = $securityContext->getToken()->getUser(); 
$securityIdentity = UserSecurityIdentity::fromAccount($user); 

// grant owner access  
$acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER); 
$aclProvider->updateAcl($acl); 

Also, wenn Sie ein neues Konto erstellen, kann ich die aktuelle geben eingeloggte in Benutzerzugriff auf das neu erstellte Konto. Aber wie gewähre ich Zugriff auf alle anderen Benutzer des Clients Zugriff auf das Konto?

Ich möchte nicht alle Benutzer durchlaufen und den obigen Code für jeden Benutzer ausführen.

So zum Beispiel, wenn alle Clients sehen, muss ich wissen, welche Clients der Benutzer Zugriff hat, oder wenn die Konten sehen, ich muss wissen, welche Konten der Benutzer Zugriff hat.

Auch wenn ein neuen Benutzer an einen Client hinzufügen, müssen die Benutzer automatisch auf Zugang zu allen Konten für diesen Client.

Als Randbemerkung, ich muss wissen, nur dann, wenn der Benutzer den Zugriff auf das Konto/Client hat. Wenn ein Benutzer Zugriff hat, dann werden sie automatisch angezeigt/bearbeitet werden dürfen/löschen usw.

+2

Wenn Sie für jeden Benutzer in bestimmte Rolle Berechtigungen zuweisen Sie Sie stattdessen rollenbasierte 'ACL' verwenden sollte ... die viel gleichermaßen Rechnung basiert. Ich sollte in der Lage sein, einen Beispielcode zu schreiben (in den nächsten Stunden). Wenn Rollen jedoch nicht Ihr Ziel sind, müssen Sie ** jeden Benutzer durchlaufen, dem Sie Berechtigungen zuweisen möchten. –

Antwort

0

Für diesen Fall ich einen benutzerdefinierten Sicherheitsdienst verwendet, die ManyToMany Beziehungen zwischen Entitäten überprüft. Es ist nicht die ideale Entscheidung, aber bedenken Sie.

Zuerst müssen wir Listener erstellen, der bei jeder Controller-Aktion ausgelöst wird.

class SecurityListener 
{ 
    protected $appSecurity; 

    function __construct(AppSecurity $appSecurity) 
    { 
     $this->appSecurity = $appSecurity; 
    } 

    public function onKernelController(FilterControllerEvent $event) 
    { 
     $c = $event->getController(); 

     /* 
     * $controller passed can be either a class or a Closure. This is not usual in Symfony2 but it may happen. 
     * If it is a class, it comes in array format 
     */ 
     if (!is_array($c)) { 
      return; 
     } 

     $hasAccess = $this->appSecurity->hasAccessToContoller($c[0], $c[1], $event->getRequest()); 

     if(!$hasAccess) { 
      throw new AccessDeniedHttpException('Access denied.'); 
     } 

    } 
} 

In Betrieb haben wir Zugriff auf Anfrage, Controller-Instanz und aufgerufene Aktion. So können wir entscheiden, ob Benutzer Zugriff haben oder nicht.

class AppSecurity 
{ 
    protected $em; 
    protected $security; 
    /** @var $user User */ 
    protected $user; 

    public function __construct(EntityManager $em, SecurityContext $security) 
    { 
     $this->em = $em; 
     $this->security = $security; 

     if($security->getToken() !== null && !$security->getToken() instanceof AnonymousToken) { 
      $this->user = $security->getToken()->getUser(); 
     } 
    } 

    /** 
    * @param $controller 
    * @param string $action 
    */ 
    public function hasAccessToContoller($controller, $action, Request $request) 
    { 
     $attrs = $request->attributes->all(); 
     $client = $attrs['client']; 

     /* db query to check link between logged user and request client */ 
    } 
} 

Wenn Sie mit sehr unangenehmen Anmerkungen wie ParamConverter können Sie ganz einfach bereit extrahieren entites von Anfrage zu verwenden.