如何使用acl (Access Control list)

编辑本页

警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 3.2,现已不再维护。

本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。

如何使用acl (Access Control list)

在复杂的应用程序中,您将经常面临这样的问题,即访问决策不能仅基于人(令牌)请求访问的对象,但也涉及正在请求访问的域对象。这就是ACL系统的用武之地。

使用ACL并不简单,对于更简单的用例,使用ACL可能有些过分。如果您的权限逻辑可以通过编写一些代码来描述(例如,检查一个博客是否由当前用户拥有),那么考虑使用选民.将被投票的对象传递给投票者,您可以使用该对象做出复杂的决策并有效地实现您自己的ACL。强制授权(例如isGranted ()part)将类似于您在本条目中看到的内容,但是您的voter类将处理幕后的逻辑,而不是ACL系统。

假设您正在设计一个博客系统,您的用户可以在其中评论您的帖子。现在,您希望用户能够编辑自己的评论,而不是其他用户的评论;此外,您希望能够编辑所有注释。在这种情况下,评论就是你想要限制访问的域对象。您可以使用Symfony采用几种方法来实现这一点,两种基本方法是(非详尽的):ob娱乐下载

  • 在业务方法中加强安全性:基本上,这意味着在每个内部都保留一个引用评论,然后将这些用户与所提供的用户进行比较令牌
  • 使用角色加强安全性:在这种方法中,您将为每个角色添加一个角色评论对象,即。ROLE_COMMENT_1ROLE_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娱乐下载组件安全AclObjectIdentity使用ob娱乐下载组件安全AclUserSecurityIdentity使用ob娱乐下载组件安全Acl许可MaskBuilderBlogController扩展控制器/ /……公共函数addCommentAction(文章帖子评论评论();/ /……设置$form,并提交数据如果形式->isSubmitted () & &形式->isValid ()) {entityManager->getDoctrine ()->getManager ();entityManager->persist (评论);entityManager->冲洗();//创建ACLaclProvider->get (“security.acl.provider”);objectIdentity= ObjectIdentity::fromDomainObject (评论);aclaclProvider->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 (身份面具);

用户现在可以查看、编辑、删除和取消删除对象。

此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。