Динамическая проверка прав на основе rbac\DbManager
Динамическая проверка прав на основе rbac\DbManager
По-моему самый частый вопрос на форуме - это настройка rbac. И это несмотря на огромное количество мануалов по его настройке на основе PhpManager. Предлагаю всем желающим модуль для работы с ролями и правами на основе DbManager - настройка прав доступа и ролей через веб-интерфейс.
Но модуль задумывался лишь как сопутствующий инструмент для поведения, которое на лету проверяет права доступа. Имхо - это очень удобно. В Yii2 легко создавать, устанавливать и использовать модули. Но "чужой" модуль не знает моих пользователей, мои роли и тп. Максимум что может внести автор чужого модуля - роль "admin" на все случаи жизни. А если я хочу более тонкую настройку прав? Переопределять все контроллеры модуля только ради прописывания прав? А завтра я еще их захочу менять. Имхо, авторы модулей не должны думать о проблемах доступа, это должно быть за пределом их компетенции. А доступы будет разруливать вот такое поведение.
Скачать модуль и поведение можно с гитхаба.
Я тестировала на своих проектах, буду признательна, если кто еще проверит работу на своем приложении.
Стоит ли добавить возможность прописывать бизнес-правила для роли или правила? Для их написания нужно понимать принципы rbac, а мне хочется чтобы использование модуля не требовало никаких доп.знаний. Подумываю над созданием универсальных бизнес-правил, например $user->getId() == $object->{$filed}
Буду рада любым замечаниям, пожеланиям, предложениям и пул-реквестам
Но модуль задумывался лишь как сопутствующий инструмент для поведения, которое на лету проверяет права доступа. Имхо - это очень удобно. В Yii2 легко создавать, устанавливать и использовать модули. Но "чужой" модуль не знает моих пользователей, мои роли и тп. Максимум что может внести автор чужого модуля - роль "admin" на все случаи жизни. А если я хочу более тонкую настройку прав? Переопределять все контроллеры модуля только ради прописывания прав? А завтра я еще их захочу менять. Имхо, авторы модулей не должны думать о проблемах доступа, это должно быть за пределом их компетенции. А доступы будет разруливать вот такое поведение.
Скачать модуль и поведение можно с гитхаба.
Я тестировала на своих проектах, буду признательна, если кто еще проверит работу на своем приложении.
Стоит ли добавить возможность прописывать бизнес-правила для роли или правила? Для их написания нужно понимать принципы rbac, а мне хочется чтобы использование модуля не требовало никаких доп.знаний. Подумываю над созданием универсальных бизнес-правил, например $user->getId() == $object->{$filed}
Буду рада любым замечаниям, пожеланиям, предложениям и пул-реквестам
Re: Динамическая проверка прав на основе rbac\DbManager
Очень удобный модуль. У меня правда не все получилось реализовать, но мне понравилась идея, так что в любом случае спасибо вам. Я новичок и пробовал разобрать весь ваш код по косточкам. Меня интересует вот этот кусок кода из поведения:
Вся моя база пустая (таблицы созданы, но я их не заполнял), а в конфиге я указал:
Я проверил, действительно, никуда не могу зайти, кроме как на site/login и site/index. Однако, если это дело проверять в режиме разработки и с панелью дебага(в продакшене эти ошибки опускаются и не выводятся на страницу), то когда я захожу на site/login или site/index, под футером у меня просто строкой пишется ошибка: "Bad Request (#400): Не достаточно прав"(на самом деле это писалось на любой странице, об этом чуть ниже). Т.е. он вроде как и дает доступ, и не дает. Тогда я подкорректировал немного код поведения для теста:
Оказалось, что куда бы я не заходил (даже на несуществующие страницы, которые выдают ошибку 404), у меня везде по футером теперь пишется: "TESTBad Request (#400): Не достаточно прав". Т.е. cheсkByRule(..) и checkPermission(..) всегда false (либо null, что не влияет). Логично, что проверка по AuthManager (я про checkPermission(..)) возвращает false, т.к. у меня пустая база данных, но если я захожу, к примеру, на site/index, то он при проверке по конфигу (cheсkByRule(..)) должен возвращать true и ничего не делать. Надеюсь, понятно объяснил свою проблему. Надеюсь на вашу помощь, ибо очень долго провозился с этим, но так ни к чему и не пришел.
Код: Выделить всё
if(!$this->cheсkByRule($action, $user, $request))
{
//И по AuthManager
if(!$this->checkPermission($route))
throw new BadRequestHttpException('Не достаточно прав');
}
Код: Выделить всё
'as AccessBehavior' => [
'class' => AccessBehavior::className(),
'rules' =>
['site' =>
[
[
'actions' => ['login', 'index'],
'allow' => true,
],
]
]
]
Код: Выделить всё
if(!$this->cheсkByRule($action, $user, $request))
{
//И по AuthManager
if(!$this->checkPermission($route))
{
echo "TEST";
throw new BadRequestHttpException('Не достаточно прав');
}
}
Re: Динамическая проверка прав на основе rbac\DbManager
Спасибо за то, что решили воспользоваться моим модулем, мне очень приятно
Проблема в том, что у вас нет доступа к дебагеру. Он отдельным запросом подгружается. Нужно добавить в конфиг правила доступа к дебагеру
"/debug/default" как-то так:
Проблема в том, что у вас нет доступа к дебагеру. Он отдельным запросом подгружается. Нужно добавить в конфиг правила доступа к дебагеру
"/debug/default" как-то так:
Код: Выделить всё
'as AccessBehavior' => [
'class' => AccessBehavior::className(),
'rules' =>
['site' =>
[
[
'actions' => ['login', 'index'],
'allow' => true,
],
]
],
['debug' =>
[
[
'allow' => true,
],
]
]
]
Re: Динамическая проверка прав на основе rbac\DbManager
Спасибо, что так быстро ответили
Но проблема все равно не решилась. Если вставлять ваш код, то выдает ошибку:
"Setting unknown property: rbac\behaviors\AccessBehavior::0"
Это вроде как логично, т.к. мы вроде как 'rules' должны передавать один массив, который состоит из конфигурация, а не два через запятую. Поправил вот так:
Все заработало, но с той же проблемой.
Но проблема все равно не решилась. Если вставлять ваш код, то выдает ошибку:
"Setting unknown property: rbac\behaviors\AccessBehavior::0"
Это вроде как логично, т.к. мы вроде как 'rules' должны передавать один массив, который состоит из конфигурация, а не два через запятую. Поправил вот так:
Код: Выделить всё
'as AccessBehavior' => [
'class' => AccessBehavior::className(),
'rules' =>
[
'site' =>
[
[
'actions' => ['index'],
'allow' => true,
],
]
'debug' =>
[
[
'allow' => true,
],
]
],
]
Re: Динамическая проверка прав на основе rbac\DbManager
У меня правда другое поведение немного, но для дебаггера так стоит
кстати удобно вынести массив _accessrules в отдельный файл c возвращаемым массивом, а в основной его require так же как params
Код: Выделить всё
[
//..........
[
'controllers' => ['debug/default'],
'actions' => [],
'allow' => true,
],
//..........
]
Код: Выделить всё
'as globalAccess'=>[
'class'=>'\common\components\behaviors\GlobalAccessBehavior',
'rules'=>require(__DIR__.'/_accessrules.php')
],
Re: Динамическая проверка прав на основе rbac\DbManager
Insolita, спасибо за наводку. Данный код работает:
Код: Выделить всё
'as AccessBehavior' => [
'class' => AccessBehavior::className(),
'rules' =>
[
'site' =>
[
[
'actions' => ['index'],
'allow' => true,
],
],
'debug/default' =>
[
[
'actions' => [],
'allow' => true,
],
]
],
]
Re: Динамическая проверка прав на основе rbac\DbManager
я новичек((
При попытке установки вылетает ошибка:
D:\OpenServer\domains\lk-ia>composer require developeruz/yii2-db-rbac «*»
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
— The requested package developeruz/yii2-db-rbac could not be found in any v
ersion, there may be a typo in the package name.
Potential causes:
— A typo in the package name
— The package is not available in a stable-enough version according to your min
imum-stability setting
see f
or more details.
Read for further common
problems.
Installation failed, reverting ./composer.json to its original content.
Что это может быть?? Помогите плиз)
При попытке установки вылетает ошибка:
D:\OpenServer\domains\lk-ia>composer require developeruz/yii2-db-rbac «*»
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
— The requested package developeruz/yii2-db-rbac could not be found in any v
ersion, there may be a typo in the package name.
Potential causes:
— A typo in the package name
— The package is not available in a stable-enough version according to your min
imum-stability setting
see f
or more details.
Read for further common
problems.
Installation failed, reverting ./composer.json to its original content.
Что это может быть?? Помогите плиз)
Re: Динамическая проверка прав на основе rbac\DbManager
Попробуйте так:fire-bug писал(а):я новичек((
Installation failed, reverting ./composer.json to its original content.
Что это может быть?? Помогите плиз)
Код: Выделить всё
D:\OpenServer\domains\lk-ia>composer require developeruz/yii2-db-rbac "dev-master"
Re: Динамическая проверка прав на основе rbac\DbManager
уже так и сделал, но все равно спасибо))
Re: Динамическая проверка прав на основе rbac\DbManager
По многочисленным просьбам в модуль добавлена страница для привязки роли пользователю.
Спасибо всем, кто пользуется данным модулем Жду новых пожеланий и предложений.
Спасибо всем, кто пользуется данным модулем Жду новых пожеланий и предложений.
-
- Сообщения: 1428
- Зарегистрирован: 2009.08.20, 22:54
- Откуда: Молдова, Бельцы
- Контактная информация:
Re: Динамическая проверка прав на основе rbac\DbManager
+1 к идее, разработка очень полезная.
Re: Динамическая проверка прав на основе rbac\DbManager
мучаюсь вторую неделю((
У меня в конфиге бекенда добавлено следующее:
в контроллере куда захожу прописано:
ни каких ролей не выдано на контроллер и я пытаясь зайти получаю вот такую ошибку:
то выводится отдельная страница с ошибкой из поставки yyi2, а не моя.
Где ошибка, в чем заключается такая проблема не могу понять((
У меня в конфиге бекенда добавлено следующее:
Код: Выделить всё
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php'),
require(__DIR__ . '/params-local.php')
);
use developeruz\db_rbac\behaviors\AccessBehavior;
return [
'id' => 'app-backend',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'backend\controllers',
'bootstrap' => ['log'],
'as AccessBehavior' => [
'class' => AccessBehavior::className(),
'rules' =>
['site' =>
[
[
'allow' => true,
],
],
'permit/access' =>
[
[
'actions' => ['role',],
'allow' => true,
],
],
'debug/default' =>
[
[
'allow' => true,
],
],
],
],
'modules' => [
'permit' => [
'class' => 'developeruz\db_rbac\Yii2DbRbac',
'params' => [
'userClass' => 'common\models\User',
]
],
],
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [ 'errorAction' => 'site/error',
],
],
'params' => $params,
];
Код: Выделить всё
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
];
}
public function action()
{
return [
// declares "error" action using a class name
'error' => 'yii\web\ErrorAction',
];
}
не знаю как это побороть, если убираю из конфига:\An Error occurred while handling another error:
exception 'yii\web\BadRequestHttpException' with message 'Не достаточно прав' in W:\domains\fczb\vendor\developeruz\yii2-db-rbac\behaviors\AccessBehavior.php:50
Stack trace:
#0 [internal function]: developeruz\db_rbac\behaviors\AccessBehavior->interception(Object(yii\base\ActionEvent))
#1 W:\domains\fczb\vendor\yiisoft\yii2\base\Component.php(541): call_user_func(Array, Object(yii\base\ActionEvent))
#2 W:\domains\fczb\vendor\yiisoft\yii2\base\Module.php(607): yii\base\Component->trigger('beforeAction', Object(yii\base\ActionEvent))
#3 W:\domains\fczb\vendor\yiisoft\yii2\base\Controller.php(139): yii\base\Module->beforeAction(Object(yii\web\ErrorAction))
#4 W:\domains\fczb\vendor\yiisoft\yii2\base\Module.php(455): yii\base\Controller->runAction('error', Array)
#5 W:\domains\fczb\vendor\yiisoft\yii2\web\ErrorHandler.php(80): yii\base\Module->runAction('site/error')
#6 W:\domains\fczb\vendor\yiisoft\yii2\base\ErrorHandler.php(101): yii\web\ErrorHandler->renderException(Object(yii\web\BadRequestHttpException))
#7 [internal function]: yii\base\ErrorHandler->handleException(Object(yii\web\BadRequestHttpException))
#8 {main}
Previous exception:
exception 'yii\web\BadRequestHttpException' with message 'Не достаточно прав' in W:\domains\fczb\vendor\developeruz\yii2-db-rbac\behaviors\AccessBehavior.php:50
Stack trace:
#0 [internal function]: developeruz\db_rbac\behaviors\AccessBehavior->interception(Object(yii\base\ActionEvent))
#1 W:\domains\fczb\vendor\yiisoft\yii2\base\Component.php(541): call_user_func(Array, Object(yii\base\ActionEvent))
#2 W:\domains\fczb\vendor\yiisoft\yii2\base\Module.php(607): yii\base\Component->trigger('beforeAction', Object(yii\base\ActionEvent))
#3 W:\domains\fczb\vendor\yiisoft\yii2\base\Controller.php(139): yii\base\Module->beforeAction(Object(yii\base\InlineAction))
#4 W:\domains\fczb\vendor\yiisoft\yii2\base\Module.php(455): yii\base\Controller->runAction('permission', Array)
#5 W:\domains\fczb\vendor\yiisoft\yii2\web\Application.php(84): yii\base\Module->runAction('permit/access/p...', Array)
#6 W:\domains\fczb\vendor\yiisoft\yii2\base\Application.php(375): yii\web\Application->handleRequest(Object(yii\web\Request))
#7 W:\domains\fczb\backend\web\index.php(18): yii\base\Application->run()
#8 {main}
Код: Выделить всё
'errorHandler' => [ 'errorAction' => 'site/error',
],
Где ошибка, в чем заключается такая проблема не могу понять((
Re: Динамическая проверка прав на основе rbac\DbManager
Какой url вы пытаетесь открыть?
permit/access/p... ? Доступ вы дали только на permit/access/role к остальным доступа нет.
permit/access/p... ? Доступ вы дали только на permit/access/role к остальным доступа нет.
Re: Динамическая проверка прав на основе rbac\DbManager
http://afczb/permit/access/permissionRoksalana писал(а):Какой url вы пытаетесь открыть?
permit/access/p... ? Доступ вы дали только на permit/access/role к остальным доступа нет.
я понимаю что дал только к role, вопрос в том почему ошибка о том что нету доступа не формируется.
Вот описания всего процесса:
1)если я делаю в контроллере проверку через can и в конфиге у меня прописан путь в вьюхе ошибок ('errorHandler' => [ 'errorAction' => 'site/error', ) то выглядит все хорошо, вот так: 2) если я переношу проверку прав в конфиг приложения (для того что бы работало на лету) то получают вот что: 3) если я удаляю при настройке проверки прав на лету из конфига приложения строку 'errorHandler' => [ 'errorAction' => 'site/error', то тогда получают ошибку вот такого вида:
как добиться при проверке на лету что бы ошибка выглядела как при проверке через can в контроллере?
Re: Динамическая проверка прав на основе rbac\DbManager
Тоже столкнулся с этой проблемой, выяснилось:polumerk писал(а):как добиться при проверке на лету что бы ошибка выглядела как при проверке через can в контроллере?
в классе \developeruz\db_rbac\behaviors\AccessBehavior в методе interception, строка 42: $action = $event->sender->requestedAction;
При вызове действия (например 'site/error') из обработчика ошибок event->sender->requestedAction остается тем же самым (т. е. действие, доступа к которому нет), повторно осуществляется проверка доступа к тому же действию, и опять выбрасывается исключение.
Нужно код поправить, например: $action = $event->sender->controller->action;
И еще: в том же классе в методе createRule в массив $this->_rules[] при повторном вызове добавляются правила, которые там уже есть, нужно проверку добавить.
Re: Динамическая проверка прав на основе rbac\DbManager
А проверку на повторение вы делали в правилах при повторном добавлении?cmjn1 писал(а):Тоже столкнулся с этой проблемой, выяснилось:polumerk писал(а):как добиться при проверке на лету что бы ошибка выглядела как при проверке через can в контроллере?
в классе \developeruz\db_rbac\behaviors\AccessBehavior в методе interception, строка 42: $action = $event->sender->requestedAction;
При вызове действия (например 'site/error') из обработчика ошибок event->sender->requestedAction остается тем же самым (т. е. действие, доступа к которому нет), повторно осуществляется проверка доступа к тому же действию, и опять выбрасывается исключение.
Нужно код поправить, например: $action = $event->sender->controller->action;
И еще: в том же классе в методе createRule в массив $this->_rules[] при повторном вызове добавляются правила, которые там уже есть, нужно проверку добавить.
Как же хорошо что вы нашли момент, я там зажимки не верные делал((
Re: Динамическая проверка прав на основе rbac\DbManager
Сделал просто проверку, что правила не пусты, т. к. конфигурируется компонент 1 раз.polumerk писал(а):А проверку на повторение вы делали в правилах при повторном добавлении?
Я сам класс не менял, просто сделал дочерний класс и его использую:
Код: Выделить всё
namespace common\components\db_rbac\behaviors;
use developeruz\db_rbac\behaviors\AccessBehavior as AccessBehaviorBase;
use ReflectionProperty;
use Yii;
use yii\di\Instance;
use yii\web\BadRequestHttpException;
use yii\web\User;
class AccessBehavior extends AccessBehaviorBase
{
protected $_rulesReflection;
public function __construct()
{
$this->_rulesReflection = new ReflectionProperty('developeruz\db_rbac\behaviors\AccessBehavior', '_rules');
$this->_rulesReflection->setAccessible(true);
}
public function interception($event)
{
$route = Yii::$app->getRequest()->resolve();
//Проверяем права по конфигу
$this->createRule();
/** @var \yii\web\User $user */
$user = Instance::ensure(Yii::$app->user, User::className());
$request = Yii::$app->getRequest();
$action = $event->sender->controller->action;
if (!$this->cheсkByRule($action, $user, $request)) {
//И по AuthManager
if (!$this->checkPermission($route)) {
if ($user->isGuest) {
$user->loginRequired();
} else {
throw new BadRequestHttpException(Yii::t('app', 'Недостаточно прав'));
}
}
}
}
protected function createRule()
{
if (empty($this->_rulesReflection->getValue($this))) {
parent::createRule();
}
}
}
И еще добавил редирект на страницу входа для незалогиненных, чтобы поведение было, как если "access" прописать в "behaviors" контроллера.
Re: Динамическая проверка прав на основе rbac\DbManager
Спасибо огромное!!!
Re: Динамическая проверка прав на основе rbac\DbManager
ОМГ, стоило уехать в отпуск, как в моем модуле нашли баги Насколько понимаю проблема только в случаи подключения модуля, как поведения в контроллере?
В любом случаи проверю и постараюсь решить
В любом случаи проверю и постараюсь решить
Re: Динамическая проверка прав на основе rbac\DbManager
Посмотрел исправленный вариант, он будет работать, если подключать в контроллере, но будет повторяться ошибка:Roksalana писал(а):В любом случаи проверю и постараюсь решить
Не будет работать, если подключать через общий конфиг.
А мой вариант не будет работать, если подключать в контроллере:))
В итоге как-то так:
Код: Выделить всё
if ($event->sender instanceof \yii\web\Application) {
$action = $event->sender->controller->action;
} elseif ($event->sender->module instanceof \yii\web\Application) {
$action = $event->sender->module->controller->action;
} else {
throw new BadRequestHttpException(Yii::t('app', 'Неверный класс, вызвавший событие проверки прав доступа'));
}