【问题标题】:Yii2 AccessControl and RBAC Update Own RecordYii2 AccessControl 和 RBAC 更新自己的记录
【发布时间】:2016-03-23 07:15:54
【问题描述】:

在关注this guide 之后,我无法让“更新自己的记录”类型的功能正常工作。这是我所拥有的。

管理员和作者角色。作者拥有imageUpdateOwn 权限,小时候拥有imageUpdate 权限。 imageUpdateOwn 权限具有分配给它的 isOwner 规则。所有其他相关/相关代码如下。

数据库

OwnerRule.php

Image 模型有一个 created_by 属性,它是记录的所有者。

public function execute($user, $item, $params)
{
    return isset($params['model']) ? $params['model']->created_by == $user : false;
}

ImageController.php 访问控制

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'allow' => true,
                    'actions' => ['update'],
                    'roles' => ['imageUpdate'],
                ],
                [
                    'allow' => true,
                    'actions' => ['delete'],
                    'roles' => ['imageDelete'],
                ],
                [
                    'allow' => true,
                    'actions' => ['index', 'view', 'create'],
                    'roles' => ['@'],
                ],
                [
                    'allow' => false,
                ],
            ],
        ],
    ];
}

ImageController.php 操作

public function actionUpdate($id)
{
    $model = $this->findModel($id);

    if (\Yii::$app->user->can('imageUpdate', ['model' => $model])) {
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    } else {
        throw new HttpException(403, 'You do not have permission to update this record.');
    }
}

在我的测试中,我以作者身份登录并上传了图像 1000,然后以管理员身份登录并上传了图像 1001。在每个用户登录时执行以下快速测试会产生预期的结果。

$image1000 = \app\models\Image::findOne(1000); // author uploaded
$image1001 = \app\models\Image::findOne(1001); // admin uploaded

echo \Yii::$app->user->can('imageUpdate', ['model' => $image1000]) . "<br>";
echo \Yii::$app->user->can('imageUpdate', ['model' => $image1001]);

当以管理员身份登录时,每个回显语句都会得到“真”。当以作者身份登录时,我只为图像 1000 获得“真”。这告诉我授权正在返回正确的权限,正如我创建的 isOwner 规则所期望的那样。

但是,当我尝试实际执行更新操作时,我什至无法通过访问控制。我没有得到我在操作中指定的 403 错误(这是我所期望的),而是得到了通用的“您不允许执行此操作”错误。这似乎是因为我将默认访问权限设置为拒绝。如果我将默认访问权限设置为允许,我可以完成操作并收到预期的 403 错误消息。这告诉我该操作不允许我通过。

我不确定imageUpdateOwn 角色是否应该列在访问控制中,但是在那里并不会改变结果(可能是因为imageUpdateimageUpdateOwn 的子级,所以作者通过后者也会有前者)。

我在上面遗漏了什么完全阻止我以作者身份登录时访问更新操作?

编辑 1

可能是因为在检查访问控制时未加载模型,因此无法评估 created_by 用户。如果是这种情况,我很困惑,因为作者通过imageUpdateOwn 拥有imageUpdate,它应该允许继续访问。除非他们只在与imageUpdateOwn 关联的规则通过时才获得imageUpdate。在这种情况下,在可以评估模型之前,作者永远不会“获得”与imageUpdate 角色关联的访问权限。这意味着我必须允许所有经过身份验证的用户访问 update 操作,并且仅在加载模型后检查操作本身的权限。

【问题讨论】:

    标签: php yii2


    【解决方案1】:

    通过进一步的测试和更多的研究,这是我发现的(希望有人可以确认)。

    管理员角色直接分配给imageUpdate,并且能够更新任何图像。作者直接分配给imageUpdateOwn,其中有imageUpdate作为一个孩子。尽管imageUpdate 是已分配权限的子级,但如果父级上的规则阻止授予父级,则不会授予该权限。基本上,如果imageUpdateOwn 评估为假(意味着作者用户不是给定图像的所有者),那么作者也不会获得imageUpdate 的子权限。

    作者角色没有通过任何记录的访问控制的原因是,在评估访问控制时,模型不可用。如果模型不可用,则附加到imageUpdateOwn 的规则将评估为假(如果您没有记录,则无法检查其所有者),这意味着其子imageUpdate 也不会被授予权限。

    解决方法是允许所有经过身份验证的用户通过访问控制,然后在操作本身中检查特定权限,例如:

    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],
        ];
    }
    ...
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);
    
        if (\Yii::$app->user->can('imageUpdate', ['model' => $model])) {
            // Save the record and redirect the user
        } else {
            throw new HttpException(403, 'You do not have permission to update this record.');
        }
    }
    

    这可确保未经身份验证的用户不允许在操作附近的任何地方进行操作,而经过身份验证的用户必须具备以下条件之一:

    1. imageUpdate 权限(分配给管理员角色)。
    2. imageUpdateOwn 权限(分配给作者角色)如果isOwner 规则评估为真(只有在我们有模型时才能评估为真,则可以检查所有者),这将授予imageUpdate 权限)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-26
      • 2011-09-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多