2012-03-11 16 views
12

Mi piacerebbe sentire alcuni pensieri sul modo migliore per ottimizzare il nostro schema per ottenere quanto segue.Il modo migliore per gestire le autorizzazioni degli oggetti utente/gruppo con Symfony2

Abbiamo un certo numero di oggetti/voci db (eventi, luoghi, ecc) alcune delle quali hanno figli oggetti (che significa si applicano le stesse autorizzazioni - immagini, il METAS, ecc)

utenti possono appartenere a gruppi in modo genitore oggetti come eventi, luoghi possono essere modificabili/visualizzabili da tutti, solo gruppo, solo un utente.

Attualmente abbiamo un utente, un gruppo di utenti e una tabella di gruppo per gestire utenti e gruppi.

Ogni oggetto padre, ad esempio le sedi come colonna per user_id e group_id.

Funziona bene (in symfony 1.4) ma è caotico - ogni query per qualsiasi cosa deve fare join complessi per ottenere possibili gruppi ecc ... Ci piacerebbe trovare un modo più semplice.

Ero davvero entusiasta del componente Sf2 ACL ma mi viene ripetuto che non dovrei usarlo per trovare oggetti che un utente può gestire, piuttosto che dovrei usare ACL per scoprire se un utente è autorizzato gestire i propri oggetti (non sembra molto utile ma qualunque).

Tutti i tentativi alternativi online che ho trovato per fare questo dicono di estrarre tutti gli oggetti da db e poi filtrarli da ACL - è carino per un sito mamma e pop - non succederà con un milione di oggetti.

Quindi ... mi piacerebbe sentire le idee su come potremmo fare questo - siamo anche aperti a lasciare symfony per qualcosa che ha una soluzione ACL scalabile ma non ho trovato nulla finora (php o ruby) così aperto anche a quello, anche se ci piacerebbe continuare a usare Sf. Nota che intendiamo usare MongoDB nel caso che importi.

risposta

11

Da come ho capito, l'ACL viene utilizzato per concedere l'accesso a un oggetto specifico a una persona specifica per scenari speciali. Quello che stai descrivendo è più generico, ma si discosta solo da ciò che Symfony2 definisce per sicurezza (questa persona ha un ruolo "admin", ma solo per gli oggetti contenuti in un particolare gruppo).

Gli ACL non devono essere utilizzati per memorizzare un sacco di cose, poiché il controllo può risultare costoso se diventa troppo grande. Quindi, inserendo un po 'di materiale qui per impostazione predefinita quando vengono aggiunti nuovi utenti o anche quando vengono aggiunti nuovi oggetti sotto un gruppo (se si utilizza l'ACL, è necessario aggiungere una voce a ogni persona nel gruppo ogni volta che si crea un nuovo oggetto), dopo un po 'sarà tassativo sulle prestazioni ...

Attualmente sto ricercando la possibilità di usare Symfony2 per un'applicazione web, ma sto colpendo un muro con questo materiale di sicurezza, come abbiamo una necessità simile. Non sono un esperto in Symfony2, ma da quello che ho guardato a, si potrebbe avere un paio di opzioni:

  1. Creare un elettore per gestire questa situazione. Gli elettori consentono di controllare i token di autorizzazione e di restituire se l'accesso è concesso o negato in base alla modalità di elaborazione. Quindi, puoi creare un Voter personalizzato che controlla il gruppo di un utente e cerca di farlo corrispondere al gruppo in cui si trova l'oggetto. In tal caso, restituisci ACCESS_GRANTED, altrimenti ACCESS_DENIED, o ACCESS_ABSTAIN se l'Elettore non è valido per il controllo corrente. EDIT: Ecco un link al ricettario Symfony2 per gli elettori:

  2. Potrebbe anche voler ricercare l'interfaccia SecurityContext. Questo fornisce il metodo "isGranted()" che si occupa di determinare l'accesso agli oggetti.Se gli elettori non sono semplicemente sufficienti, potresti dover seguire la strada della creazione di una nuova classe SecurityContext; Penso che questo sarebbe un po 'più coinvolto però.

Come ho detto, non sono un professionista e non ho una soluzione; queste sono solo alcune delle direzioni che sto cercando di provare a risolvere (quello che sento è) un problema simile. Spero che questo aiuti un po '.

1

È passato un po 'di tempo da quando ho inviato la mia risposta originale a questo, ma volevo seguire un'altra soluzione, quella che stiamo usando al momento.

Mentre Symfony fornisce un livello di sicurezza/ACL da utilizzare, non è necessario che lo abbia per utilizzarlo o almeno completamente.

in quasi ogni punto nel tempo nel codice, si può buttare a Il livello di sicurezza Symfony\Component\Security\Core\Exception\AccessDeniedException e volontà "calcio in" e gestirlo per voi, come reindirizzare gli utenti a una pagina di login, ecc

Alcuni questa interazione potrebbe richiedere una configurazione del firewall un po 'più avanzata per funzionare esattamente come si desidera.

Per farla breve, mentre Symfony fornisce alcuni meccanismi e funzionalità per aiutare a creare ACL, non è necessario lavorare per adattare i dati e i processi in ciò che hanno definito.

Per il nostro sistema come esempio, abbiamo account, ruoli e gruppi nel nostro sistema (insieme alle autorizzazioni). Inoltre dividiamo le sezioni dei dati anche in dipartimenti. Mentre gli utenti possono avere ruoli e autorizzazioni a livello globale, possono anche avere accesso specifico del dipartimento. Questa configurazione realizzata utilizzando le funzioni integrate di ACL di Symfony e gli strumenti di controllo degli accessi sono quasi inutilizzabili (non intendendo che i loro strumenti siano inutili, anzi sono grandi, semplicemente non si adattano alla nostra custodia d'uso). Quindi, abbiamo creato il nostro servizio (che utilizza alcune query ottimizzate) in cui passiamo i dati rilevanti relativi a un controllo e lancia l'appropriato Symfony\Component\Security\Core\Exception\AccessDeniedException quando un controllo fallisce.

Problemi correlati