2013-02-13 56 views
13

Symfony的ACL過濾了我的教訓查詢允許我授予訪問權限的實體,然後檢查:如何使用Symfony的ACL

if (false === $securityContext->isGranted('EDIT', $comment)) { 
    throw new AccessDeniedException(); 
} 

但是,如果我有成千上萬的實體在數據庫中,用戶有隻能訪問其中的10個,我不想將所有實體加載到內存中並對它們進行水合。

如何在僅對用戶有權訪問的實體(SQL級別)進行篩選時如何做簡單的「SELECT * FROM X」?

+1

你看過這個回答嗎? http://stackoverflow.com/questions/9652755/best-way-to-manage-user-group-object-permissions-with-symfony2 – 2013-02-26 20:03:19

+0

你嘗試使用[createQuery](http://docs.doctrine-project .org/en/latest/reference/dql-doctrine-query-language.html#dql-select-clause)方法? – 2013-02-25 13:43:26

回答

3

那麼它是:這是不可能的

在去年,我一直在研究一種替代ACL系統,它允許直接在數據庫查詢中進行過濾。

我公司最近同意開放源碼,所以這裏是:http://myclabs.github.io/ACL/

+1

雖然有一個解決方法。可以列出ACE的SecurityIdentity和UserSecurityIdentity,然後將WHERE子句注入查詢而不加入,只是標識。 – gregor 2014-05-23 16:20:46

+0

是的,但是這是一個類似於'WHERE id IN(1,2,3,...)'這樣的查詢,當它給出很多ID時效率會很低:(但是你說得對,值得一提的是,那也是2 DB查詢,而不是一個(使用JOIN) – 2014-05-24 11:32:32

+0

不正確,WHERE IN()應該很快 - http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_in。對於ID數量的限制取決於允許的查詢數據包大小,默認情況下它是16MB(可增加到1GB),足以使查詢中至少有1百萬個IDS(我認爲)。查詢數量取決於您存儲的位置ACL規則 - 可以在一個文件或memcached中 - 所以一起查詢 – gregor 2014-05-26 14:57:00

-1

你可以看看Doctrine filters。這樣你可以擴展所有查詢。我還沒有這樣做,並且存在一些限制。但也許它可以幫助你。您將找到ACL數據庫表here的說明。

UPDATE

每個過濾器將返回一個字符串,所有這些字符串將被添加到SQL查詢,像這樣:

SELECT ... FROM ... WHERE ... AND (<result of filter 1> AND <result of filter 2> ...) 

而且表的別名被傳遞到過濾器的方法。所以我認爲你可以在這裏添加子查詢來過濾你的實體。

+2

感謝您的回答,我沒有看到它。 Doctrine過濾器沒有幫助,因爲它們不允許與表聯接,它們只允許在WHERE子句中添加SQL。 – 2014-03-15 09:36:22

0

正如在前面的討論中所指出的@gregor,

在第一個查詢,獲取列表(用自定義查詢)用戶有權訪問的所有object_identity_ids(針對特定實體/類別X)。

然後,當查詢實體/類別X的對象列表時,將「IN(object_identity_ids)」添加到您的查詢

Matthieu,我不滿意的回答更多的猜測(因爲我的猜測沒有增加任何有價值的交談)。所以我在這個方法(數字海洋5 $ /月VPS)上做了一些基準測試。

Benchmark

正如預期的那樣,表的大小使用數組方法時並不重要。但是,龐大的陣列尺寸的確會讓事情失去控制。

那麼,Join approachIN array approach

當數組大小很大時,JOIN的確更好。但是,這是假設我們不應該考慮表格大小。原來,實際上IN數組更快 - 除非有一個大對象表,並且acl條目幾乎覆蓋了每個對象(請參閱鏈接問題)。

我在一個單獨的問題上擴展了我的推理。請看When using Symfony's ACL, is it better to use a JOIN query or an IN array query?