2011-01-10 11 views
8

Quindi sto creando un piccolo sito utilizzando cakephp e il mio ACL è impostato in modo che ogni volta che viene creato un pezzo di contenuto, venga creata una regola ACL per collegare il proprietario del contenuto al contenuto effettivo. Ciò consente a ciascun proprietario di modificare/eliminare il proprio contenuto. Questo metodo sembra così inefficiente, perché c'è una quantità equivalente di regole ACL come contenuto nel database. Ero curioso, come fanno i grandi siti, con milioni di pezzi di contenuti, a risolvere questo problema?In che modo i siti di grandi dimensioni ottengono le autorizzazioni a livello di riga?

risposta

10

Con i siti di grandi dimensioni su cui ho lavorato le autorizzazioni di accesso sono state determinate a livello di applicazione. Il database associava il contenuto alla registrazione di un utente, quindi nel livello di accesso ai dati/livello di business logic ha stabilito se l'utente dispone o meno di diritti sufficienti per accedere al contenuto.

Per un sito di grandi dimensioni con contenuti dinamici penso che questo sarebbe probabilmente il modo migliore per gestire la cosa.

MODIFICA: per aggiungere un esempio più concreto.

Esempio: Ok diciamo che abbiamo un semplice sito di archiviazione file in cui un utente può accedere solo ai propri dati o dati che sono stati esplicitamente condivisi con loro da un altro utente.

Dal momento che questa applicazione è abbastanza semplice in quanto è semplicemente servendo file ha solo tre tabelle del database, che sono:

Users Table which has columns: 
     UserId <int> PK 
     UserName <varchar> 
     HashedPassword <varchar> 
Files Table which has columns: 
     FileId <int> PK 
     FileOwnerId <int> FK (this has a foreign key relationship with UserId in the users table) 
     FileName <varchar> 
     MimeType <varchar> 
     FileData <blob> 
SharedFile reference table which has columns: 
     SharedFileIndex <int> PK 
     FileId <int> FK 
     UserId <int> FK 

ora alcune regole di base che ci vorranno per definire nel nostro livello di accesso ai dati è che quando quando un utente ha effettuato l'accesso, può accedere ai file di cui sono proprietari e ai file condivisi da altri utenti. Quindi, attraverso le stored procedure o costruendo la query da inviare al server del database, mi assicuro che le mie query restituiscano solo quei record ai quali hanno accesso.

Ecco la query SQL GetUsersFileList di base per quando un utente accede a:

SELECT FileId, FileName, FileType 
FROM Files 
WHERE FileOwnerId = @UserId 

come si può vedere qui stiamo usando una query con parametri per ottenere poi i file che un utente è il proprietario del. Inoltre richiederemmo anche i file condivisi per la visualizzazione all'utente.

Ora, se si assume che ogni file avrà un proprio URL univoco come ad esempio:

http://mydomain.com/filehandler.php?fileId=123546 

Poi, quando si cerca di ottenere il file che usiamo una query simile come sopra per cercare di ottenere i dati del file:

SELECT FileName, FileType, FileData 
FROM Files 
LEFT OUTER JOIN SharedFiles on Files.FileId = SharedFiles.FileId 
WHERE Files.FileId = @FileId AND (FileOwnerId = @UserId OR SharedFiles.UserId = @UserId) 

quindi, vedete, quando si cerca di ottenere il file che stiamo ancora usando l'ID utente nella query in tal modo se l'utente non ha il file sia condiviso con loro o non sei il proprietario del file il risultato dalla query sarà 0 righe.

Quindi le autorizzazioni sono determinate da ciò a cui un utente è associato nel database ma l'effettiva applicazione viene eseguita scrivendo attentamente il codice di accesso ai dati e/o controlli aggiuntivi nel livello della logica aziendale prima di servire il contenuto.

EDIT2: mi è più familiare con MSSQL così le mie domande di cui sopra sono in T-SQL così la sintassi potrebbe essere un po 'fuori per MySql.

EDIT3: livello di business logic sostituito con livello di accesso ai dati come in questo esempio, gli unici controlli effettuati sono all'interno delle stesse query di accesso ai dati.

EDIT4: Ok rimettersi in riferimento al livello della business logic in quanto applicazioni più complesse avrebbero bisogno di schemi di autorizzazione più complessi che potrebbero richiedere controlli aggiuntivi nel livello della business logic.

+0

Sembra interessante, potresti approfondire un po 'di più (ad esempio aggiungendo un piccolo esempio di come lo realizzeresti)? – nico

+0

Sicuro. Lavorando su un aggiornamento ora. – Adrian

0

La stessa regola si applica a siti grandi e piccoli: se si desidera un controllo più specifico, è necessario memorizzare più dati nel database. Il problema che stai cercando di risolvere [consentire agli utenti di gestire solo il loro contenuto] può essere risolto utilizzando un semplice link ID utente tra le tabelle [ad esempio users.id < -> articles.userId], non è necessario collegare ogni riga con l'utente. Suggerirei di utilizzare regole più generali e di memorizzare solo eccezioni [ad esempio consentendo agli utenti specificati di modificare il contenuto di altri utenti] come dati esterni.

2

Invece di avere un ACL separato per ogni elemento di contenuto, è possibile avere un ACL separato per ogni diverso insieme di autorizzazioni. La maggior parte degli elementi di contenuto per un determinato utente avrà le stesse autorizzazioni, in modo che tutti possano puntare allo stesso ACL. Ciò potrebbe anche consentire di memorizzare nella cache i controlli delle autorizzazioni (ad es. "L'utente 123 ha il permesso di leggere ACL 456"). Alla fine avrete pochissimi ACL, solo quelli standard e le poche eccezioni.

Problemi correlati