我有Hibernate请求,它返回要显示的元素列表。我需要检查当前用户是否能够查看每个返回的元素。我能做到这样的事情
for (Element e : elements) {
SecurityUtils.getSubject().hasPermission("element:view:" + e.id);
}
但是此代码将为每个元素生成对数据库的x个请求。所以检查的速度将是O(n)。
如何改进我的解决方案?是否有可能获得速度O(1)?
答案 0 :(得分:2)
主题上有一个名为isPermittedAll(String ...)
的方法,如果主题具有所有权限,则会返回true
。
虽然,老实说我不知道在数据库查询方面有多高效(如果有的话)。
答案 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的实施方式。