У меня есть прецедент, когда мне нужно назначить пользователю право редактировать высокодинамичные элементы, которые могут быть в сотнях или тысячах. Каждый пользователь, принадлежащий к одному типу или группе , должен быть назначен некоторым из этих элементов (и разные пользователи могут иметь доступ к тем же элементам Компании ). Кроме того, эти предметы могут быстро расти или исчезать. Эти элементы не имеют неотъемлемых отношений с пользователями, но должны быть произвольно назначены им.
Позволяет называть эти предметы фирменными элементами.
Таким образом, я хочу, чтобы иметь возможность назначать товарные позиции пользователям и отменить этот доступ динамически. Эти назначения затем используются внутри контроллеров для проверки того, может ли какое-либо действие продолжать … Концептуально проблема всегда одна и та же: проверьте, имеет ли пользователь доступ к определенному элементу / строке в таблице, таблице « Элементы компании ».
Моя идея состояла в том, чтобы использовать систему yii yii yii , пытаясь сохранить дерево авторизации статическим , избегая при этом создания или удаления ролей или задач каждый раз, когда создается или удаляется элемент компании . Вместо этого мне было интересно, могу ли я сделать это, используя параметр $data
в assign($itemName, $userId, $bizRule, $data)
и дерево, подобное следующему:
$params['companyItemId']
внутри $data['companyItemsAllowed']
; во время присваивания, должен получить $data
содержащий массив идентификаторов компаний, которым должно быть разрешено редактировать пользователя!
Yii::app()->user->checkAccess('editItem', array('companyItemId' => 666));
Таким образом, всякий раз, когда нам нужно изменить назначение пользователя на позиции компании , единственное, что нам нужно сделать, это изменить массив $data['companyItemsAllowed']
в исходном задании. Роль всегда одна и та же!
Я написал небольшую структуру для контроля доступа. Это просто, мало и легко. Моя мотивация заключалась в том, чтобы отделить контроль доступа моих приложений от других фреймворков, потому что я считаю, что контроль доступа из других фреймворков очень связан с фреймворком.
Например, в Yii, где вы должны запрограммировать его в контроллере, и мне это не нравится, потому что это очень скучные новые правила программы, когда вы добавляете новое действие ( из Yii Wiki ):
class PostController extends CController { public function accessRules() { return array( array('deny', 'actions' => array('create', 'edit'), 'users' => array('?'), ), array('allow', 'actions' => array('delete'), 'roles' => array('admin'), ), array('deny', 'actions' => array('delete'), 'users' => array('*'), ), ); } }
ИМХО, это должно быть сделано динамично. Вы должны иметь возможность запрограммировать правило в своей административной системе визуально, а затем программу разработчика выполнить действие и модель соответствующим образом, а затем готово.
Чтобы интегрировать мою библиотеку с приложениями Yii, я использую импорт, например:
$path = Yii::getPathOfAlias('application.services.RapidAuthorization'); Yii::setPathOfAlias('RapidAuthorization', $path);
И я использую beforeControllerAction()
из модулей (модулей) для интеграции.
Когда у меня будет время, я напишу ручную интеграцию для нескольких фреймворков, сначала с которыми у меня есть опыт Yii, Zend и Symfony. И переведите документацию на английский язык. Но теперь код является английским.
Я надеюсь, что, по крайней мере, вы получите представление о том, как написать свой контроль доступа.
Вы можете использовать концепцию Yii для владельца данных в своей реализации управления доступом.
Первым шагом к реализации этого в вашем собственном приложении является указание контроллеру включить это правило. Это делается путем перезаписи функции filters ().
class ContentController extends Controller { public function filters() { return array( 'accessControl' ); } public function accessRules() { } }
Флаг 'accessControl' указывает, что для управления данными применяется управление доступом. Фактические бизнес-правила определены в функции accessRules () и указаны выражение управления доступом, которое будет оцениваться для обеспечения требуемого управления. И пример реализации функции.
public function accessRules() { return array( array('allow', // allow all users to perform 'index' and 'view' actions 'actions' => array('view'), 'users' => array('*'), ), array('allow', // allow authenticated user to perform 'add' action 'actions' => array('add'), 'users' => array('@'), ), array('allow', // allow only the owner to perform 'modify' 'delete' actions 'actions' => array('modify', 'delete'), 'expression' => array('ContentController','isMyRecord') ), array('deny', // deny all users 'users' => array('*'), ), ); }
IsMyRecord – это метод, который будет запущен, который возвращает true или false, чтобы указать, разрешено ли действие.
public function isMyRecord(){ if (Yii::app()->user->checkAccess( ...)) return true; else return false; }
Я решил использовать следующий подход, решив, что простое поддержание массива элементов компании внутри $data['companyItemsAllowed']
не подходит для этих требований:
Users
и CompanyItems
; назовите его association_table
; создал дерево RBAC, как показано в вопросе, но где bizRule
был примерно следующим:
$ret = Yii::app()->dbConnection->createCommand('SELECT EXISTS(SELECT 1 FROM `association_table` WHERE user_id=:userId AND company_item_id=:companyItemId)') ->queryScalar(array(':userId' => $params['userId'], 'companyItemId' => $params['companyItemId'])); return $ret;
Это позволяет мне поддерживать интерфейс управления доступом , например:
Yii::app()->user->checkAccess('editItem', array('companyItemId' => 666));
(напомним, что нам не нужно передавать userId
в массив $params
!.)
Конечно , это отделяет фактическое назначение разрешений для элементов компании из системы RBAC : я назначаю editCompanyItemRole
для какого-либо пользователя, используя механизмы RBAC, предлагаемые Yii, но каждый фактический элемент должен назначаться индивидуально, вставляя строку в association_table
…
Поэтому, хотя сначала подумал о поддержке массива элементов компании внутри $data
, вероятно, будет работать, я думаю, что это лучше и гибче. Кроме того, похоже, что общая идея о bizRule
работает.