Право доступа YiiRules ошибочно

Я пытаюсь создать сайт с помощью Yii и оказался в ситуации, требующей некоторых разъяснений по метафоре управления доступом в Yii. В частности, можно переопределить метод accessRules в CController .

<Сильный> Необходимое условие:

Вот код, созданный по умолчанию Gii, очень похожий на документация :

public function accessRules()
{
    return array(
        array('allow', //allow all users to perform 'index' and 'view' actions
            'actions'=>array('index','view'),
            'users'=>array('*'),
        ),
        array('allow',//allow authenticated user to perform 'create' and 'update' actions
            'actions'=>array('create','update'),
            'users'=>array('@'),
        ),
        array('allow',//allow admin user to perform 'admin' and 'delete' actions
            'actions'=>array('admin','delete'),
            'roles'=> array('admin'),
        ),
        array('deny', //deny all users
            'users'=>array('*'),
        ),
    );
}

Вопрос:

Для меня неясно, есть ли , почему нам нужно определять правила доступа для разных пользователей и групп и разные действия вместо проверки прав только одного текущего пользователя и действия? - здесь выделен курсивом, мой главный вопрос подчеркнут, на всякий случай он может не так понят для читателей (авторы ответов).

Этот код выполняется в контексте конкретного запроса, для которого конкретный контроллер , конкретный action и конкретный пользователь ) уже известный . Если, например, пользователь является гостем, я не вижу причин для определения правил для роли «admin» или для аутентифицированных пользователей.

<Сильный> Обоснование:

После некоторой разработки я подошел к следующей реализации:

public function accessRules()
{
    return array(
      array(Yii::app()->user->hasRights()?'allow':'deny'),
      );
}

где hasRights - это простой пользовательский метод, добавленный в потомок CWebUser :

class WebUser extends CWebUser
{
  private $ACL =//ACL example
    array('user' =>//controller id
      array('index' => User::AC_MODERATOR,//action ids
            'view' => User::AC_MODERATOR,
            'create' => User::AC_MODERATOR,
            'update' => User::AC_ADMIN,
            'delete' => User::AC_ADMIN,
            'admin' => User::AC_ADMIN),
          //...
      );

  public function hasRights()
  {
    return (Yii::app()->user->getState('accessRights') >=
      $this->ACL[Yii::app()->controller->id][Yii::app()->controller->action->id]);
  }
}

Как вы можете видеть, hasRights использует текущие пользовательские «права» (как обычно, чтение из базы данных), текущий контроллер и действие для вычисления одного логического кода true или false code> значение как решение о доступе.

Что не так с этим подходом? Почему Yii не использует что-то простое по умолчанию?

Генерируемый Gii accessRules выше не только выглядит чрезмерно, но также подразумевает, что правила доступа разбросаны среди многих контроллеров. В моем подходе используется одиночный и компактный ACL.

2
nl ja de

2 ответы

Вот где я думаю, вы в замешательстве.

Прежде всего, Yii фактически рассматривает только текущего пользователя и текущее действие. Точно так же, как вы получили текущие разрешения для контроллера, захватив вложенный массив, проиндексированный идентификатором контроллера, Yii создает экземпляр вашего контроллера и смотрит только на эти правила доступа. Кроме того, точно так же, как вы смотрите только на разрешения конкретного действия, Yii рассматривает только правила, относящиеся к текущему действию. Он также получает доступ к этим разрешениям так же легко, как вы возвращаете значение вложенного массива.

Что касается пользователя, он также смотрит только на текущего пользователя; текущее имя пользователя, текущую роль пользователя и т. д. Разница в том, что существует множество атрибутов Yii в пределах правила, в отличие от единственного значения разрешения, связанного с пользователем.

Кажется, что вам не нравится этот подход, вы думаете, что разрешения должны обрабатываться в одном месте. В некоторых случаях это может быть проще, но в других труднее. Что происходит, когда в каждом контроллере имеется несколько контроллеров и несколько действий? Теперь у вас есть очень большой массив для управления, который ссылается на данные из нескольких разных контекстов. В способе, которым Yii это делает, текущий контроллер имеет контроль над тем, как можно получить доступ к структуре данных. Это связано с структурой MVC Yii и концепцией инкапсуляции.

В некоторых отношениях ваше решение более элегантно, но оно зависит от идеи о том, что разрешения должны будут когда-либо быть структурированы в каскадной одной направленной структуре. Я имею в виду, что ваши разрешения похожи на один длинный коридор с дверями, отделяющими одну область от другой. Если у пользователя нет ключа к одной двери, они не должны иметь доступ к следующему и т. Д. Но что произойдет, если в вашем примере вам нужен пользователь для просмотра содержимого и обновления без возможности создать новый контент? Это гораздо более сложный сценарий, который нужно будет обрабатывать с использованием ролей. Итак, вам придется обрабатывать правила в вашем массиве, как это делает Yii. За исключением объектно-ориентированного подхода Yii, у вас есть все встроенное в один длинный массив.

Поэтому, возможно, ваше решение будет работать в некоторых случаях, но я уверен, что вы можете понять, почему Yii выбрал свой подход, поскольку он будет работать по умолчанию для гораздо большего числа ситуаций.

3
добавлено
Благодарю. Я принимаю ваш ответ, потому что он кажется рациональным. Да, Yii работает так же, как вы описали, но использует слишком многословный код для этого, что мне не нравится. Мой подход не меньше OO, а затем Yii - единственная разница заключается в рефакторинге с WebUser , который получает часть функций службы ACL из Controller . И Yii, и мой код используют массивы под капотом. Что касается концепции « hallway », ее можно легко расширить до таблицы произвольного доступа, просто используя побитовые операции. Сейчас мне это не нужно. Тем не менее я признаю подход Yii более гибким.
добавлено автор Stan, источник
Хороший вопрос о побитовых операциях. Одно из предостережений, однако, может осложниться, если у вас есть контроллер, который взаимодействует с более чем одной моделью. Что делать, если у вас более одного действия «создать», или у вас есть действие, которое создает две модели; или что, если вам нужно, чтобы кто-то получил разрешение на создание модели, но нужно ограничить определенное свойство на этой модели. Просто подумать. Вы изучали расширения прав Yii? Я использовал это с некоторым успехом: yiiframework.com/extension/rights
добавлено автор ethan, источник

Yii implements a hierarchical RBAC scheme via its CWebApplication ->authManager application component, which actually similar to what you did,

Take a look at this

<Сильный> ИЗМЕНИТЬ

"let us suppose that we use RBAC and add some rules into the accessRules method, such as with admin role in the example above." 

вы не добавляете правила в метод accessRules, когда используете RBAC

что вы делаете, вы определяете иерархию авторизации, которая включает в себя три шага 1) определить авторизацию itmes, которая включает в себя роли и операции, это будет храниться в БД, в таблице authitem

Например. <Сильный> Операции

siteAddProduct->in this case 'site' is the controller name and addProduct is the action in 'site' controller
sitedeleteProduct ...etc

Roles

admin,editor...etc

2) Установить взаимосвязь между элементами авторизации (между ролью и операциями), которые будут храниться в таблице authitemchild

например.

admin -> siteAddProduct
editor -> sitedeleteProduct
admin->editor

3) назначить роли для пользователей приложений, которые будут храниться в таблице authassignment

for example userid 1 ->admin

теперь в вашем базовом контроллере (при условии, что у вас есть класс контроллера, из которого выходят все остальные контроллеры в приложении) вы переопределяете метод beforeAction() и проверяете доступ к зарегистрированному пользователю (текущему пользователю), используя

Yii::app()->user->checkAccess($operation);

$ - запрошенный контроллер + действие

you can get the controller name using $this->id and action name using $this->getAction()->id

0
добавлено
Спасибо за ответ. Я знаю это. RBAC требует выполнения дополнительной процедуры для настройки ролей и назначения их пользователям, которые кажутся странными, поскольку соответствующие данные уже доступны в моделях домена. Мне не нужно такое дублирование. В любом случае, допустим, мы используем RBAC и добавляем некоторые правила в метод accessRules , например, с ролью администратора в приведенном выше примере. Вопрос остается тем же: зачем нам определять правила для других действий и пользователей, чем текущие действия и пользователя?
добавлено автор Stan, источник
Я знаю, что такое RBAC. Я просто отметил, что мы используем роли, определенные в RBAC, в методе accessRules , добавляя, таким образом, правила доступа с участием ролей. Ответ еще не отвечает на вопрос.
добавлено автор Stan, источник
Мой вопрос о реализации accessRules по умолчанию, а не о RBAC.
добавлено автор Stan, источник
я только что отредактировал свой ответ
добавлено автор wonde, источник
почему вы используете метод accessRules, если вы уже внедрили RBAC
добавлено автор wonde, источник
phpGeeks
phpGeeks
3 620 участник(ов)

Best PHP chat Еще: @dbGeeks - базы данных @phpGeeksJunior - новичкам @moscowProgers - IT Москва @ebanoePhp - весёлый канал о PHP @laravel_pro - Laravel @jobGeeks - вакансии @jsChat - JS Правила: https://t.me/phpGeeks/764859 ДР - 28.03.2016

PHP
PHP
1 309 участник(ов)

Группа про современный PHP. Обсуждаем ООП, TDD, BDD, DDD, SOLID, GRASP и прочие крутые базворды Для ознакомления: https://gist.github.com/mkusher/711bd46f0b62fbae851182e6fb3b1839 Группа PHP для новичков @phpGeeksJunior Вакансии: https://t.me/fordev

PHP — вакансии, поиск работы и аналитика
PHP — вакансии, поиск работы и аналитика
1 251 участник(ов)

Публикуем вакансии и запросы на поиск работы по направлению PHP, Laravel, Symfony, Yii и т.д. Здесь всё: full-time, part-time, remote и разовые подработки. См. также: @qa_jobs, @devops_jobs, @javascript_jobs, @nodejs_jobs, @uiux_jobs, @products_jobs

Yii Framework
Yii Framework
1 076 участник(ов)

Russian and english speaker comunity

phpGeeksJunior
phpGeeksJunior
980 участник(ов)

Группа для новичков. Не стесняйтесь задавать вопросы по php. Не флудить!!!! Правила и полезные ссылки https://gist.github.com/exileed/a53dd0617b35a705ff44b38c8028e6a5 Бест от пхпгикс https://t.me/best_of_phpgeeks

phpclub.ru
phpclub.ru
872 участник(ов)

Официальный чат phpclub.ru - остерегайтесь подделок #rules Правила группы - уважайте друг друга. Скриншоты -> ссылками. Код -> pastebin.com. Вакансии строго -> https://goo.gl/4bNxym, в чат ссылку. За рекламу и мат - БАН!

Devall | PHP
Devall | PHP
272 участник(ов)

Пристанище для восходящих звёзд разработки, которые перейдут на более адекватные языки. http://combot.org/chat/-1001014863761 Инвайт: j.mp/devallphp

Yii - вакансии, работа, фриланс
Yii - вакансии, работа, фриланс
264 участник(ов)

Пишите тут свои вакансии, заказы. Просим сразу озвучивать зарплату или бюджет за проект.