2012-05-15 15 views
1

我有Hibernate請求,返回我要顯示的元素列表。我需要檢查的是當前用戶能夠查看每個返回的元素。我可以這樣做如何檢查Shiro權限列表中的元素?

for (Element e : elements) { 
    SecurityUtils.getSubject().hasPermission("element:view:" + e.id); 
} 

但是這段代碼會爲每個元素產生x個數據庫請求。所以檢查速度將是O(n)。

我該如何改進我的解決方案?是否有可能獲得速度O(1)?

回答

2

對於主題,有一種方法稱爲isPermittedAll(String ...),如果主題具有所有權限,則返回true

參見:http://shiro.apache.org/static/current/apidocs/org/apache/shiro/subject/Subject.html#isPermittedAll%28java.lang.String...%29

雖然,說實話,我不知道它是在數據庫查詢方面如何更有效(如果有的話)。

+0

我需要過濾元素。我認爲,如果用戶無法訪問1個元素,「isPermittedAll」將爲所有元素返回「false」 –

0

鑑於你的榜樣,你可能要做到以下幾點:

我用
String[] permissions = new String[elements.size()]; 

for (int i = 0; i < elements.size(); i++) { 
    permissions[i] = "element:view:" + e.id; 
} 

boolean[] allowed = SecurityUtils.getSubject().isPermitted(permissions); 

List<Element> allowedElements = new ArrayList<Element>(); 

for (int i = 0; i < elements.size(); i++) { 
    //1:1 match on entries in allowed to elements 
    if (allowed[i]) { 
     allowedElements.add(elements[i]); 
    } 
} 

//allowedElements now contains the set of elements the user is permitted to access 
return allowedElements; 

的主題API方法是在這裏:boolean[] isPermitted(String... permissions)

對這個缺點的方法是,你有效地結束了迭代你的元素列表兩次。但是,由於您不必爲每個元素進行數據庫調用,因此最終會保存。

有一點需要注意,您的運行時間可能會有所不同,具體取決於您的安全Realm的實施方式。