首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Yii2 AccessControl和RBAC更新自己的记录

Yii2 AccessControl和RBAC更新自己的记录
EN

Stack Overflow用户
提问于 2016-03-22 04:05:56
回答 1查看 1.4K关注 0票数 1

在遵循本指南之后,我无法获得“更新自己的记录”类型的功能。这是我所拥有的。

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

数据库

OwnerRule.php

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

代码语言:javascript
运行
复制
public function execute($user, $item, $params)
{
    return isset($params['model']) ? $params['model']->created_by == $user : false;
}

ImageController.php AccessControl

代码语言:javascript
运行
复制
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 action

代码语言:javascript
运行
复制
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。在登录时执行以下快速测试,因为每个用户都会产生预期的结果。

代码语言:javascript
运行
复制
$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]);

当以管理员身份登录时,我会得到每个echo语句的"true“。当以作者身份登录时,我只在图像1000中获得“真”。这告诉我,授权正在按照我创建的isOwner规则返回正确的权限。

但是,当我实际尝试执行update操作时,我甚至无法通过访问控制。我没有得到我在操作中指定的403错误(这正是我所期望的),而是得到了一般的“您不允许执行此操作”错误。这似乎是因为我的默认访问设置要拒绝。如果我将默认访问设置为allow,则可以通过该操作并获得预期的403错误消息。这说明我的行动不允许我通过。

我不确定是否应该在访问控制中列出imageUpdateOwn角色,但是拥有它不会改变结果(大概是因为imageUpdateimageUpdateOwn的一个子角色,所以通过拥有后者,作者也将拥有前者)。

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

编辑1

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

EN

回答 1

Stack Overflow用户

发布于 2016-03-22 14:19:21

通过进一步的测试和更多的研究,我发现了(希望有人能证实)。

管理角色被直接分配给imageUpdate,并且能够更新任何图像。作者被直接分配给imageUpdateOwn,它以imageUpdate作为子级。尽管imageUpdate是已分配权限的子权限,但如果父权限上的规则阻止父权限的授予,则不会给出它。基本上,如果imageUpdateOwn计算为false (意味着作者用户不是给定图像的所有者),那么作者也不会获得imageUpdate的子权限。

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

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

代码语言:javascript
运行
复制
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权限(分配给author角色),如果isOwner规则的计算结果为true (只有当我们有模型以便检查所有者时,isOwner权限才能被授予isOwner权限)。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36145903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档