如何使用ACL根据特定用户的权限(例如EDIT)过滤域对象列表? [英] How do one use ACL to filter a list of domain-objects according to a certain user's permissions (e.g. EDIT)?

查看:102
本文介绍了如何使用ACL根据特定用户的权限(例如EDIT)过滤域对象列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Web应用程序中的Symfony2中使用ACL实现时,我们遇到了一个用例,在该用例中,建议的使用ACL的方式(检查单个域对象的用户权限)变得不可行.因此,我们想知道是否可以使用ACL API的某些部分来解决我们的问题.

When using the ACL implementation in Symfony2 in a web application, we have come across a use case where the suggested way of using the ACLs (checking a users permissions on a single domain object) becomes unfeasible. Thus, we wonder if there exists some part of the ACL API we can use to solve our problem.

用例在控制器中,该控制器准备要在模板中呈现的域对象列表,以便用户可以选择要编辑的对象.用户无权编辑数据库中的所有对象,因此必须相应地过滤列表.

The use case is in a controller that prepares a list of domain objects to be presented in a template, so that the user can choose which of her objects she wants to edit. The user does not have permission to edit all of the objects in the database, so the list must be filtered accordingly.

(除其他解决方案外)这可以根据两种策略来完成:

This could (among other solutions) be done according to two strategies:

1)查询过滤器,该过滤器将给定查询附加来自当前用户ACL的一个或多个对象的有效对象ID.即:

1) A query filter that appends a given query with the valid object ids from the present user's ACL for the object(or objects). I.e:

WHERE <other conditions> AND u.id IN(<list of legal object ids here>)

2)查询后过滤器,用于从数据库中检索完整列表后,删除用户没有正确权限的对象.即:

2) A post-query filter that removes the objects the user does not have the correct permissions for after the complete list has been retrieved from the database. I.e:

$objs   = <query for objects>
$objIds = <getting all the permitted obj ids from the ACL>
for ($obj in $objs) {
    if (in_array($obj.id, $objIds) { $result[] = $obj; } 
}
return $result;

第一个策略是可取的,因为数据库正在执行所有筛选工作,并且都需要两个数据库查询.一种用于ACL,另一种用于实际查询,但这可能是不可避免的.

The first strategy is preferable as the database is doing all the filtering work, and both require two database queries. One for the ACLs and one for the actual query, but that is probably unavoidable.

在Symfony2中是否可以实施这些策略之一(或达到预期效果的某种方法)?

Is there any implementation of one of these strategies (or something achieving the desired results) in Symfony2?

推荐答案

假定您有要检查的域对象的集合,则可以使用security.acl.provider服务的findAcls()方法预先进行批量加载. isGranted()调用.

Assuming that you have a collection of domain objects that you want to check, you can use the security.acl.provider service's findAcls() method to batch load in advance of the isGranted() calls.

条件:

用测试实体填充数据库,对我数据库中的随机用户具有MaskBuilder::MASK_OWNER的对象许可权,对于角色IS_AUTHENTICATED_ANONYMOUSLY具有MASK_VIEW的类许可权; MASK_CREATE表示ROLE_USERROLE_ADMINMASK_EDITMASK_DELETE.

Database was populated with test entities, with object permissions of MaskBuilder::MASK_OWNER for a random user from my database, and class permissions of MASK_VIEW for role IS_AUTHENTICATED_ANONYMOUSLY; MASK_CREATE for ROLE_USER; and MASK_EDIT and MASK_DELETE for ROLE_ADMIN.

测试代码:

$repo = $this->getDoctrine()->getRepository('Foo\Bundle\Entity\Bar');
$securityContext = $this->get('security.context');
$aclProvider = $this->get('security.acl.provider');

$barCollection = $repo->findAll();

$oids = array();
foreach ($barCollection as $bar) {
    $oid = ObjectIdentity::fromDomainObject($bar);
    $oids[] = $oid;
}

$aclProvider->findAcls($oids); // preload Acls from database

foreach ($barCollection as $bar) {
    if ($securityContext->isGranted('EDIT', $bar)) {
        // permitted
    } else {
        // denied
    }
}

结果:

使用调用$aclProvider->findAcls($oids);,分析器显示我的请求包含3个数据库查询(以匿名用户身份).

With the call to $aclProvider->findAcls($oids);, the profiler shows that my request contained 3 database queries (as anonymous user).

没有对findAcls()的调用,同一请求包含51个查询.

Without the call to findAcls(), the same request contained 51 queries.

请注意,findAcls()方法以30为批次(每批次2个查询)加载,因此您的查询数将随较大的数据集而增加.该测试在工作日结束后约15分钟内完成;如果有机会,我将仔细研究并彻底检查相关方法,以查看ACL系统是否还有其他有用的用途,并在此处报告.

Note that the findAcls() method loads in batches of 30 (with 2 queries per batch), so your number of queries will go up with larger datasets. This test was done in about 15 minutes at the end of the work day; when I have a chance, I'll go through and review the relevant methods more thoroughly to see if there are any other helpful uses of the ACL system and report back here.

这篇关于如何使用ACL根据特定用户的权限(例如EDIT)过滤域对象列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆