Yii2 RBAC失败-它阻止了所有操作,或者也允许来宾了所有操作

问题描述 投票:0回答:1

我一直与Yii2 RBAC纠缠了一个星期,现在从各种站点收集信息,但我无法使其正常工作。我目前的情况包括两种方式:RBAC阻止所有内容,或者来宾可以访问所有内容。

我的主要问题是让RBAC允许用户访问分配给他们的页面。奇怪的是Yii::$app->user->can("/" . Yii::$app->controller->id . "/" . Yii::$app->controller->action->id);函数为经过身份验证的用户正确返回true,但是如果我将其嵌入到控制器的访问控制规则中,它将无法工作(给出403)。

return [
    'access' => [
        'class' => AccessControl::className(),
        'rules' => [
            [
                'actions' => ['index', 'about', 'error', 'test'],
                'allow' => true,
            ],
            [
                'actions' => ['login'],
                'allow' => true,
                'roles' => ['?'],
            ],
            [
                'actions' => ['logout'],
                'allow' => true,
                'roles' => ['@'],
            ],
            [
                'allow' => Yii::$app->user->can("/" . Yii::$app->controller->id . "/" . Yii::$app->controller->action->id),
                'actions' => [Yii::$app->controller->action->id],
            ]
        ],
    ],
    'verbs' => [
        'class' => VerbFilter::className(),
        'actions' => [
            'logout' => ['post'],
        ],
    ],
];

我找到了解决此问题的方法,而不是将该条件硬编码到规则数组中,而是在return命令之前插入一小段代码,如果用户确实可以,则将当前操作添加为通过array_merge作为允许的操作访问该位置。现在可以正确应用经过身份验证的用户权限,但是,它始终为来宾返回true(他们基本上拥有对所有内容的权限)。

$rules = [];
if (!Yii::$app->user->isGuest) {
    if (Yii::$app->user->can("/" . Yii::$app->controller->id . "/" . Yii::$app->controller->action->id)) {
        $rules[] = [
            'allow' => true,
            'actions' => [Yii::$app->controller->action->id],
        ];
    }
}
return [
    'access' => [
        'class' => AccessControl::className(),
        'rules' => array_merge($rules, [
            [
                'actions' => ['index', 'about', 'error', 'test'],
                'allow' => true,
            ],
            [
                'actions' => ['login'],
                'allow' => true,
                'roles' => ['?'],
            ],
            [
                'actions' => ['logout'],
                'allow' => true,
                'roles' => ['@'],
            ],
        ]),
    ],
    'verbs' => [
        'class' => VerbFilter::className(),
        'actions' => [
            'logout' => ['post'],
        ],
    ],
];

我已经这样测试了访客权限:

var_dump(Yii::$app->user->can("/site/dashboard"));
die;

我执行的任何操作都会返回bool(true)。如果我已登录,它将按照auth数据库表中的预期功能运行。

可以提供任何帮助,以发现我的解决方案中的错误或指出如何将RBAC与来宾和行为正确地使用。或者可能是为了帮助我理解为什么在没有经过身份验证的用户的情况下为什么返回true。

谢谢。

authentication yii2 behavior rbac
1个回答
0
投票

您的代码中的问题是您试图传递User函数can()错误的参数。在文档中指出:

can()公共方法检查用户是否可以执行以下操作:由给定的权限指定。

但是您尝试传递网址。

您必须在RBAC规则中分配如下权限:admin has权限accessAdminDash控制台/控制器/ RbacController

$auth = Yii::$app->authManager;
$dashboard = $auth->createPermission('accessAdminDash');
$dashboard->description = 'Admin manager panel';
$auth->add($dashboard);
//It can be more permissions
$admin = $auth->createRole('admin');
$admin->description = 'Administrator';
$admin->ruleName = $rule->name;
$auth->add($admin);
//Can be more Roles
//assign Permission to a role
$auth->addChild($admin, $dashboard);

然后,您可以像下面这样检查特定user的权限:

Yii::$app->user->can('accessAdminDash'); //here is your permission

并且在执行控制器操作时,您可以检查或创建一个私有方法来检查当前用户:

if(Yii::$app->user->can('accessAdminDash'))
{
   //Ok this user CAN access
}
throw new ForbiddenHttpException();

或在AccessControl中像这样检查角色:

public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                      'actions' => ['admin-page'],
                      'allow' => true,
                      'roles' => ['admin'], //Here is your role
                    ]
                ],
            ],
        ];
    }

希望这会给您正确的方向。

© www.soinside.com 2019 - 2024. All rights reserved.