Php Yii2访问控制和RBAC更新自己的记录
在完成以下操作后,我无法使“更新自己的记录”类型的功能正常工作。这是我的 管理员和作者角色。作者拥有Php Yii2访问控制和RBAC更新自己的记录,php,yii2,Php,Yii2,在完成以下操作后,我无法使“更新自己的记录”类型的功能正常工作。这是我的 管理员和作者角色。作者拥有imageUpdateOwn权限,作为孩子,作者拥有imageUpdate权限。imageUpdateOwn权限具有分配给它的isoowner规则。所有其他相关/相关代码如下所示 数据库 OwnerRule.php 图像模型具有一个由属性创建的,该属性是记录的所有者 public function execute($user, $item, $params) { return isset
imageUpdateOwn
权限,作为孩子,作者拥有imageUpdate
权限。imageUpdateOwn
权限具有分配给它的isoowner
规则。所有其他相关/相关代码如下所示
数据库
OwnerRule.php
图像
模型具有一个由属性创建的,该属性是记录的所有者
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]);
$image1000=\app\models\Image::findOne(1000);//作者上传
$image1001=\app\models\Image::findOne(1001);//管理员上传
echo\Yii::$app->user->can('imageUpdate',['model'=>$image1000])。“
”;
echo\Yii::$app->user->can('imageUpdate',['model'=>$image1001]);
当以管理员身份登录时,我得到每个echo语句的“true”。当以作者身份登录时,我仅对图像1000获得“true”。这告诉我授权正在返回我创建的ISOOwner规则所期望的正确权限
然而,当我试图实际执行更新操作时,我甚至无法通过访问控制。我没有得到我在操作中指定的403错误(这是我所期望的),而是得到了一般的“不允许执行此操作”错误。这似乎是因为我的默认访问设置为拒绝。如果我将默认访问设置为允许,我就可以执行该操作,并得到预期的403错误消息。这告诉我行动不允许我通过
我不确定是否应该在访问控制中列出imageUpdateOwn
角色,但将其放在那里不会改变结果(可能是因为imageUpdate
是imageUpdateOwn
的子角色,因此,通过使用后者,作者也将拥有前者)
我在以作者身份登录时完全无法访问更新操作的上述内容中缺少了什么
编辑1
可能是因为在检查访问控制时没有加载模型,所以无法评估用户创建的_。如果是这样的话,我很困惑,因为作者通过imageUpdateOwn
的方式进行了imageUpdate
,应该允许继续访问。除非它们仅在与imageUpdateOwn
关联的规则通过时获取imageUpdate
。在这种情况下,作者永远不会“获得”与imageUpdate
角色关联的访问权限,直到可以评估模型。这意味着我必须允许所有经过身份验证的用户访问更新
操作,并在加载模型后仅检查操作本身内部的权限。通过进一步的测试和研究,我发现了以下内容(希望有人能够确认)
管理员角色直接分配给imageUpdate
,可以更新任何图像。作者被直接分配到imageUpdateOwn
,其子级为imageUpdate
。尽管imageUpdate
是已分配权限的子级,但如果父级上的规则阻止授予父级,则不会授予该权限。基本上,如果imageUpdateOwn
的计算结果为false(意味着作者用户不是给定图像的所有者),则作者也不会获得imageUpdate
的子权限
作者角色未通过任何记录的访问控制的原因是,在评估访问控制时,模型不可用。如果模型不可用,则附加到imageUpdateOwn
的规则将计算为false(如果您没有记录,则无法检查其所有者),这意味着也不会授予其子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.');
}
}
这可确保不允许未经身份验证的用户靠近操作,而经过身份验证的用户必须具有以下之一:
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.');
}
}
imageUpdate
权限(分配给管理员角色)
imageUpdateOwn
权限(分配给作者角色),如果isoowner
规则的计算结果为true,则该权限将授予imageUpdate
权限(如果我们有模型,则只能计算为true,以便检查所有者)