2012-08-28 13 views
5

Sono occupato con un'applicazione Symfony2 che richiede alcune autorizzazioni ACL.Symfony2 Accesso ACL a più oggetti per più utenti

Sono un principiante con Symfony2, quindi non sono sicuro che sto guardando nel modo giusto.

Ho più client, ciascuno con più account.

Ho un super amministratore (ROLE_SUPER_ADMIN) che ha accesso a tutti i client e tutti gli account. Quindi ho un ruolo di amministratore (ROLE_ADMIN), a cui sarà consentito solo l'accesso a un client specifico e tutti gli account per quei client. Poi ci sono agenti (ROLE_AGENT), che dovrebbero avere solo l'autorizzazione per determinati account per i client.

ho visto la documentazione di symfony che, per conferire un utente l'accesso a un oggetto specifico, posso utilizzare il seguente codice:

// 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); 

Così quando si crea un nuovo account, posso dare la corrente loggati accesso utente all'account appena creato. Ma come concedere l'accesso a tutti gli altri utenti del client per accedere all'account?

Non voglio eseguire il ciclo di tutti gli utenti ed eseguire il codice precedente per ogni utente.

Quindi, per esempio, quando visualizzo tutti i client, ho bisogno di sapere a quali client l'utente ha accesso, o quando visualizzo gli account, ho bisogno di sapere a quali account l'utente ha accesso.

Anche quando si aggiunge un nuovo utente a un client, l'utente deve automaticamente avere accesso a tutti gli account per quel client.

Come nota a margine, ho solo bisogno di sapere se l'utente ha accesso all'account/cliente. Se un utente ha accesso, allora essi sono autorizzati automaticamente per visualizzare/modificare/cancellare ecc

+2

Se è necessario assegnare autorizzazioni a ciascun utente in un ruolo specifico, è necessario utilizzare "ACL" basato sui ruoli anziché ... che è molto simile all'account. Dovrei essere in grado di scrivere codice di esempio (nelle prossime ore). Tuttavia, se i ruoli non sono qualcosa che stai cercando, ** dovrai ** iterare attraverso ogni utente a cui vuoi assegnare il permesso .... –

risposta

0

Per questo caso ho usato un servizio di sicurezza personalizzato che consente di verificare le relazioni tra entità ManyToMany. Non è la decisione ideale, ma tieni a mente.

Per prima cosa dobbiamo rendere l'ascoltatore che verrà attivato ad ogni azione del controller.

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 servizio abbiamo accesso alla richiesta, all'istanza del controllore e all'azione richiamata. Quindi possiamo prendere una decisione se l'utente ha accesso o meno.

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 */ 
    } 
} 

Se si utilizza annotazioni molto brutte come ParamConverter si può facilmente estrarre pronto per l'uso entités dalla richiesta.

Problemi correlati