在silex

时间:2016-07-05 18:48:39

标签: symfony silex

我对symfony / silex中的ACL很困惑,以及如何让它们为我工作。

我一直在考虑基于模块的解决方案 - >动作。然而,阅读ACL,一切似乎都基于角色,这对于我试图实现的实现来说是广泛的。

我将拥有用户,并且所有用户都属于某个角色(管理员,用户等...)。但是,该角色更多地是您可以执行的操作的指导(因为它设置具有该角色的用户的默认权限),即用户可以执行的实际操作集。这些操作实际上是基于系统具有的模块以及实际授予任何用户读取,添加,删除更新以及除此之外的任何其他动词的权限。

所以例如: 角色#1:是管理员

  • 可以阅读用户
  • 可以发布用户
  • 可以放用户
  • 可以删除用户

角色#2:管理员

  • 可以阅读用户
  • 可以发布用户
  • 无法放置用户
  • 无法删除用户

由于我计划拥有多个不同的模块(用户,付款,产品等),并且每个管理员都可以拥有或撤销权限,因此它们不适合ROLE_ADMIN,ROLE_SUPER_ADMIN,ROLE_USER类型的角色

我正在思考ROLE_VIEW_USERS,ROLE_ADD_USERS,ROLE_EDIT_USERS这些内容,并且用户可能会有100个这样的小角色,并且每个控制器都有选民,决定是否可以执行某些操作。

这有意义吗?

1 个答案:

答案 0 :(得分:2)

您正在混淆ACL和角色。它们都与权限有关,但它们的接近和运作方式各不相同。

角色本身并不依赖于特定资源。另一方面,ACL是,并且该链接是持久的。用户可以通过选民使用资源(或看似是这样)。

https://symfony.com/doc/current/security/voters.html#creating-the-custom-voter

用户特定的ACL,例如如果用户具有特定访问权限定义的PER资源,那么您将需要更多的东西。

看看SF食谱:

https://symfony.com/doc/current/cookbook/security/acl.html https://symfony.com/doc/current/cookbook/security/acl_advanced.html

所有者/主人/操作员

  • 修改
  • 查看
  • 删除
  • 创建

所有资源(这是使用ROLES完成的)

ROLE_USER CAN

  • 编辑自己
  • 查看自己
  • DELETE OWN
  • 创建

自有资源(此部分由ACL或选民完成)

选民有效地创建了自己的ACL,因此没有持久权限,除非你明确地做了一个(此时我会去ACL)。 ACL的用例与选民的用例基本相同,选择一个与另一个是一个复杂的问题。

内置的ACL信息来自数据库,但根据SF文档:“它可以包含数千万[记录]而不会显着影响性能。”

非常简单?可以使用选民。

如果您不想维护自己的资源规则(选民),并且不介意ACL的复杂性,或者保留+缓存权限,则可以使用ACL。

请注意,在创建资源时,ACL的复杂性通常如下(尽管可以将其放入服务中):

$aclProvider = $this->get('security.acl.provider');
$objectIdentity = ObjectIdentity::fromDomainObject($resource);
$acl = $aclProvider->createAcl($objectIdentity);
$tokenStorage = $this->get('security.token_storage');
$user = $tokenStorage->getToken()->getUser();
$securityIdentity = UserSecurityIdentity::fromAccount($user);
$acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER);
$aclProvider->updateAcl($acl);

对于上一个场景,您可以使用ROLE_USER来确保经过身份验证的用户实际上是实际用户而不是AUTHENTICATED_ANONYMOUSLY以及选民或ACL以确保他们只能编辑自己的资源,并在他们的ROLE中覆盖它是ROLE_ADMIN。 (假设用户在注册后获得ROLE_USER)

security.yml中的示例

# This could be done via @Secure(roles="ROLE_USER")
access_control:
    - { path: ^/my/api/endpoint, role: IS_USER, requires_channel: https }
    - { path: ^/my/admin/api/endpoint, role: IS_ADMIN, requires_channel: https }

controller :: action

中的示例
// check for edit access
if (
    false === $authorizationChecker->isGranted('EDIT', $resource) &&
    false === $this->get('security.context')->isGranted('ROLE_ADMIN')
) {
    throw new AccessDeniedException();
}

这是StackOverflow中的另一个QA,它也提供了一些示例:

Symfony 2 ACL and Role Hierarchy

你也可以为这些东西使用注释:

https://symfony.com/doc/current/best_practices/security.html#authorization-i-e-denying-access(它显示了一个人如何与另一个人合作)。

如果有任何部分需要进一步解释,请告诉我。

谢谢。