1

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

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

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

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

4

3 回答 3

2

有一个在 Subject 上调用的方法,如果 Subject 拥有所有权限isPermittedAll(String ...),它将返回。true

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

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

于 2012-05-16T03:48:50.673 回答
0

shiro 支持缓存,如果你这个列表构造很多,你可以使用这种类型的动作。 http://shiro.apache.org/caching.html

于 2012-05-25T10:27:49.357 回答
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;

我使用的 Subject API 方法在这里:boolean[] isPermitted(String... permissions)

这种方法的缺点是您实际上最终会迭代您的元素列表两次。但是,由于您不必为每个元素进行数据库调用,因此您最终会保存。

需要注意的一点是,您的运行时间可能会根据您的安全领域的实现方式而改变。

于 2013-06-17T20:18:53.303 回答