如何使用acl (Access Control list)
编辑本页警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 3.0,现已不再维护。
读本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。
如何使用acl (Access Control list)
在复杂的应用程序中,您将经常面临这样的问题,即访问决策不能仅基于人(令牌
)请求访问的对象,但也涉及正在请求访问的域对象。这就是ACL系统的用武之地。
假设您正在设计一个博客系统,您的用户可以在其中评论您的帖子。现在,您希望用户能够编辑自己的评论,而不是其他用户的评论;此外,您自己也希望能够编辑所有的评论。在这种情况下,评论
就是你想要限制访问的域对象。您可以使用Symfony采用几种方法来实现这一点,两种基本方法是(非详尽的):ob娱乐下载
- 在业务方法中加强安全性:基本上,这意味着在每个内部都保留一个引用
评论
,然后将这些用户与所提供的用户进行比较令牌
. - 使用角色加强安全性:在这种方法中,您将为每个角色添加一个角色
评论
对象,即。ROLE_COMMENT_1
,ROLE_COMMENT_2
等。
两种方法都是完全有效的。然而,它们将您的授权逻辑与业务代码耦合在一起,这使得业务代码在其他地方的可重用性降低,也增加了单元测试的难度。此外,如果许多用户都可以访问单个域对象,您可能会遇到性能问题。
幸运的是,有一个更好的方法,你现在就会发现。
引导
现在,在你最终开始行动之前,你需要做一些引导。首先,您需要配置ACL系统应该使用的连接:
- YAML
- XML
- PHP
1 2 3 4 5 6
# app / config / security.yml安全:#……acl:连接:默认的
请注意
ACL系统需要来自Doctrine DBAL(默认可用)或Doctrine MongoDB(使用MongoDBAclBundle)。但是,这并不意味着您必须使用Doctrine ORM或ODM来映射您的域对象。你可以为你的对象使用任何你喜欢的映射器,无论是Doctrine ORM, MongoDB ODM, Propel, raw SQL等。选择权在你。
配置连接后,必须导入数据库结构。幸运的是,有这样一个任务。简单地执行如下命令:
1
$ PHP bin/console初始化acl
开始
回到开头的小示例,现在可以为它实现ACL。
一旦创建了ACL,就可以通过创建访问控制条目(ACE)来授予对象访问权,以巩固实体和用户之间的关系。
新建ACL并添加ACE
12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
/ / src / AppBundle /控制器/ BlogController.php名称空间AppBundle\控制器;使用ob娱乐下载\包\FrameworkBundle\控制器\控制器;使用ob娱乐下载\组件\安全\核心\异常\AccessDeniedException;使用ob娱乐下载\组件\安全\Acl\域\ObjectIdentity;使用ob娱乐下载\组件\安全\Acl\域\UserSecurityIdentity;使用ob娱乐下载\组件\安全\Acl\许可\MaskBuilder;类BlogController扩展控制器{/ /……公共函数addCommentAction(文章$帖子){$评论=新评论();/ /……设置$form,并提交数据如果($形式->isValid ()) {$entityManager=$这->getDoctrine ()->getManager ();$entityManager->persist ($评论);$entityManager->冲洗();//创建ACL$aclProvider=$这->get (“security.acl.provider”);$objectIdentity= ObjectIdentity::fromDomainObject ($评论);$acl=$aclProvider->createAcl ($objectIdentity);//获取当前登录用户的安全标识$tokenStorage=$这->get (“security.token_storage”);$用户=$tokenStorage->getToken ()->getUser ();$securityIdentity= UserSecurityIdentity::fromAccount ($用户);//授予所有者访问权限$acl->insertObjectAce ($securityIdentity, MaskBuilder::MASK_OWNER);$aclProvider->updateAcl ($acl);}}}
在这个代码片段中有两个重要的实现决策。现在,我只想强调两点:
首先,你可能已经注意到了- > createAcl ()
不直接接受域对象,而只接受ObjectIdentityInterface
.这个额外的间接步骤允许您即使手头没有实际的域对象实例也可以使用acl。如果您想检查大量对象的权限,而不需要实际水合这些对象,这将是非常有用的。
另一个有趣的部分是- > insertObjectAce ()
调用。在本例中,您授予当前登录的用户对Comment的所有者访问权。的MaskBuilder: MASK_OWNER
是预定义的整数位掩码;不要担心掩码构建器会抽象出大部分技术细节,但是使用这种技术可以在一个数据库行中存储许多不同的权限,从而极大地提高性能。
提示
ace被检查的顺序很重要。作为一般规则,您应该在开头放置更具体的条目。
检查访问
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
/ / src / AppBundle /控制器/ BlogController.php/ /……类BlogController{/ /……公共函数editCommentAction(评论$评论){$authorizationChecker=$这->get (“security.authorization_checker”);//检查编辑权限如果(假= = =$authorizationChecker->isGranted (“编辑”,$评论)) {扔新AccessDeniedException ();}/ /……检索实际的注释对象,并在这里进行编辑}}
在本例中,检查用户是否拥有编辑
许可。在内部,Symfony将ob娱乐下载权限映射到几个整数位掩码,并检查用户是否拥有其中任何一个。
请注意
您最多可以定义32个基本权限(根据您的操作系统,PHP可能在30到32之间变化)。此外,还可以定义累积权限。
累积的权限
在上面的第一个示例中,仅授予用户老板
基地的许可。虽然这也有效地允许用户在域对象上执行任何操作,如查看、编辑等,但在某些情况下,您可能希望显式授予这些权限。
的MaskBuilder
可以通过组合几个基本权限轻松地用于创建位掩码:
1 2 3 4 5 6 7 8
$构建器=新MaskBuilder ();$构建器->add (“视图”)->add (“编辑”)->add (“删除”)->add (“恢复”);$面具=$构建器->get ();/ / int (29)
这个整数位掩码可以用来授予用户你上面添加的基本权限:
1 2
$身份=新UserSecurityIdentity (“约翰”,“实体AppBundle \ \用户”);$acl->insertObjectAce ($身份,$面具);
用户现在可以查看、编辑、删除和取消删除对象。