Duplicazione della logica di controllo dell'accesso alle query del database e del componente dell'applicazione

2

La nostra applicazione web ha un sistema di controllo accessi complesso che incorpora basato sui ruoli e a livello di oggetto privilegi.

Nel livello della business logic, questo è implementato da un componente che ottiene (e memorizza nella cache) tutti i dati necessari con una query batch e calcola il tipo e il livello di accesso dell'utente a qualsiasi oggetto nel sistema. (Un'ottimizzazione futura sarebbe il condizionamento condizionato in base ai dati di cui abbiamo bisogno per una particolare richiesta.)

Tuttavia, la logica dei privilegi vista in questo componente viene duplicata altrove nelle query del database. (Abbiamo bisogno di nascondere i dati nelle schermate di elenco che l'utente non ha il privilegio di visualizzare.)

Come possiamo ridurre o eliminare questa duplicazione di logica tra il componente di controllo di accesso dell'applicazione e le nostre query di database?

Mi vengono in mente due approcci. Sono sicuro che ce ne sono altri.

  • Verifica il privilegio di visualizzazione nell'applicazione per ogni riga restituita dal server tramite query dagli schermi di elenco.
  • Spostare più della logica di controllo degli accessi in una funzione memorizzata che può essere richiamata dalle query e dal codice dell'applicazione.

Le risposte dovrebbero difendere i meriti del metodo proposto rispetto ad altri metodi. Ad esempio, se il mio secondo approccio suggerito è auspicabile, perché? Se hai suggerito un terzo approccio, perché ha vinto entrambi i miei approcci?

    
posta Matthew Rodatus 21.07.2011 - 15:41
fonte

2 risposte

1

La mia risposta sarebbe l'approccio 3:

Utilizza gli stessi Oggetti che fai nel livello aziendale per ripristinare le schermate di elenco.

Avresti:

  1. Rimuovi la logica duplicata dal DB, non è necessario ricordare e apportare correzioni duplicate
  2. Avere tutta la business logic nella stessa lingua, nessuna traduzione in T o PSQL richiesta
  3. Riutilizza codice esistente

Credo che questo sia l'approccio 1 e 2 sia perché richiede meno codice, e dovrebbe anche richiedere meno test di regressione.

    
risposta data 29.07.2011 - 15:52
fonte
1

Attualmente sto lottando con alcuni di questi problemi e stavo cercando gli approcci di altre persone quando mi sono imbattuto in questa domanda. Ho pensato di buttare qui alcuni pensieri nel caso in cui aiutassero qualcuno a seguire questa strada più tardi.

L'approccio che ho deciso ha il seguente:

  • Il livello del modello non ha alcuna logica di controllo dell'accesso, con l'eccezione che gli oggetti del modello rispondono a un metodo che accetta un utente corrente come parametro e restituisce un oggetto di controllo di accesso.
  • Gli oggetti del livello controllo accessi contengono riferimenti all'oggetto modello e all'oggetto utente corrente e rispondono a messaggi come can_show? (sì, questo è in Ruby), can_edit? , can_destroy? , can_show_some_attribute_name? , can_modify_some_attribute_name? , ecc. Nota che questo significa che esiste un controllo di accesso a livello di campo.
  • Esiste un livello decoratore per il modello che viene utilizzato per le viste. La decorazione richiede che venga fornito un utente corrente. I decoratori intercettano tutti i metodi di accesso degli attributi e li confrontano con l'oggetto di controllo degli accessi prima di consentire l'operazione. Le operazioni di lettura restituiscono zero se l'accesso è vietato e le operazioni di scrittura generano un errore nella stessa situazione. Per semplificare l'uso, i decoratori delegano tutti i metodi che iniziano con can_ all'oggetto controllo accessi.
  • Attualmente sto attaccando il problema dell'implementazione di un sistema di query. Ad esempio, se un utente sceglie di nascondere il proprio numero di telefono da utenti pubblici, una query per trovare utenti con un determinato numero di telefono non dovrebbe restituire quel record. Allo stesso modo, se si richiede che i risultati vengano ordinati per numero di telefono, non si dovrebbe essere in grado di dedurre che un determinato numero di telefono deve essere compreso tra quelli per i record adiacenti. Per ora ho deciso di semplificare l'implementazione assumendo che le query SQL vengano eseguite senza rispettare il controllo degli accessi (che dovrebbe restituire un super set di risultati) e quindi il sistema di query filtrerà i risultati (inclusa la verifica che tutti i condizionali siano soddisfatti e rifare l'ordinamento) usando l'oggetto controllo accessi per controllare l'accesso. Pertanto, il sistema di query utilizza il modello Generatore per archiviare la logica della query per la propria implementazione e per passarla all'ORM.

La parte della query sembra essere la più difficile. Mi piacerebbe essere in grado di tradurre il controllo degli accessi a livello di record direttamente nelle query SQL per motivi di prestazioni, anche se non riesco a tradurre anche il controllo degli accessi a livello di campo.

    
risposta data 10.05.2013 - 00:15
fonte

Leggi altre domande sui tag