如何查看元素列表的Shiro权限?

时间:2012-05-15 15:06:18

标签: java grails shiro

我有Hibernate请求,它返回要显示的元素列表。我需要检查当前用户是否能够查看每个返回的元素。我能做到这样的事情

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

但是此代码将为每个元素生成对数据库的x个请求。所以检查的速度将是O(n)。

如何改进我的解决方案?是否有可能获得速度O(1)?

3 个答案:

答案 0 :(得分:2)

主题上有一个名为isPermittedAll(String ...)的方法,如果主题具有所有权限,则会返回true

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

虽然,老实说我不知道​​在数据库查询方面有多高效(如果有的话)。

答案 1 :(得分:0)

shiro支持缓存,如果您对此列表构建很多,可以使用此类型操作。 http://shiro.apache.org/caching.html

答案 2 :(得分: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的实施方式。