0

我有一个与经过身份验证的用户一起使用的多应用程序。
所有这些应用程序可以一起部署到不同的客户端,但使用相同的用户数据库。
例如连锁酒店。
用户的角色信息在每个请求的标头中可用。

例如,经理在他自己的酒店拥有完全访问权限,但在另一家酒店只有读取权限。
前任:

{
    ["organization":"paris","roles":[ADMIN,ROOT]],
    ["organization":"london","roles":[READ]]
}

我如何处理组织的多个角色级别?
我在 symfony 中阅读了一些关于选民和角色的文档,但没有关于某种群体中的角色。

4

2 回答 2

1

选民是要走的路

// src/Security/PostVoter.php
namespace App\Security;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;

class OrganisationVoter extends Voter
{
    // these strings are just invented: you can use anything
    const READ= 'READ';
    const EDIT = 'EDIT ';

    protected function supports($attribute, $subject); bool //todo
    protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
    {
        // [...] check class like documentation
        $organisation= $subject;

        switch ($attribute) {
            case self::READ:
                return $this->canView($organisation, $user);
            case self::EDIT:
                return $this->canEdit($organisation, $user);
        }
    }

    private function canView(Organisation $organisation, User $user)
    {
        //here your logic if your user has the same organisation
    }

    private function canEdit(Organisation $organisation, User $user)
    {
        //here your logic if your user has the same organisation than the one in parameter and the good level of right (admin, root)
    }
}

然后在你的控制器(或树枝或任何地方)

    if ($this->security->isGranted(OrganisationVoter::EDIT, $organisation)) {
        return true;
    }
于 2019-03-14T20:25:44.707 回答
0

你所描述的已经写满了“基于属性的访问控制”。可帮助您将授权与要保护的应用程序/API 外部化/分离。这意味着您可以独立于授权逻辑开发功能。

有几个标准 - 即 XACML 和ALFA(授权的缩写语言)。

这是架构的样子:

XACML 架构

  • 策略执行点 (PEP) 拦截业务流并创建一个授权请求,并将其发送给 PDP
  • 策略决策点 (PDP) 根据配置的策略评估传入请求。它最终将决定返回给 PEP
  • PDP 可以使用策略信息点 (PIP) 来检索丢失的元数据(用户的部门、角色、位置;资源的部门、所有者……)

上一个答案迫使您实施选民。这非常脆弱,需要随着您的需求变化而定期编码和更新。在 ALFA 中,您不需要这样做。您只需用简单的古英语编写使用您感兴趣的属性的策略。例如:

  • 具有角色 ==“经理”的用户可以对类型 ==“酒店”的对象执行操作 ==“查看”
  • 如果hotel.owner == user.name ,角色==“manager”的用户可以对类型==“hotel”的对象执行操作==“edit”
于 2019-05-02T15:52:54.003 回答