Дизайн RBAC

Обсуждаем разработку фреймворка: дизайн компонентов, API, пакеты
yiiliveext
Сообщения: 499
Зарегистрирован: 2019.08.13, 01:49

Re: Дизайн RBAC

Сообщение yiiliveext » 2019.10.07, 14:19

raketa писал(а):
2019.10.07, 13:42
Понятно что в идеале создавать "КладовщикСтажер", или "КладовщикСтажерСтажера", "КладовщикПоВсемКромеОООРомашка" и тд и тп, но есть ситуации когда проще не плодить такие роли, это не в теория это практика. Будет столько ролей что будет сложно сделать правильный выбор между "КладовщикСтажер" и например "КладовщикСтаршийСтажер"
Вполне допускаю, что давать разрешения непосредственно пользователям для вас в вашем случае - это единственный выход, хотя я вам тоже это все не из теории рассказываю. И вы даже в чем-то правы с точки зрения философии Yii. Понимаете в чем штука, когда разработчики пишут фреймворк и все делают правильно, то на выходе получается Symfony, а когда начинают срезать углы для простоты, то выходит Yii. В итоге в Symfony на порядок сложнее наговнокодить чем в Yii, потому что чтобы сделать неправильно, там надо приложить усилие, а в Yii неправильно получается само собой. Ну а поскольку Yii3 поменял философию (хотя, на самом деле, это никто, как ни странно, не декларировал), то я считаю, что все нужно делать правильно, как оно должно быть. А неправильно всегда можно сделать, но для этого нужно приложить усилие, как в случае со скрытыми ролями.
Другое дело что $user->can('роль') это зло, потому что роль сама по себе это не разрешение на действие.
С этим, я думаю, многие согласны, ждем решения samdark.

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Дизайн RBAC

Сообщение samdark » 2019.10.08, 00:13

На данный момент:

1. Оставил возможность назначить permission пользователю напрямую.
2. Убрал возможность проверять наличие роли через userHasPermission(). Надеюсь, это форсирует правильное использование RBAC.

yiiliveext
Сообщения: 499
Зарегистрирован: 2019.08.13, 01:49

Re: Дизайн RBAC

Сообщение yiiliveext » 2019.10.08, 09:34

samdark писал(а):
2019.10.08, 00:13
На данный момент:

1. Оставил возможность назначить permission пользователю напрямую.
2. Убрал возможность проверять наличие роли через userHasPermission(). Надеюсь, это форсирует правильное использование RBAC.
2. Хорошая новость.
1. Подумайте над возможностью реализации ACL. Во многих проектах этого будет достаточно и многим проще для понимания. Возможно надо будет сделать общий AuthManagerInterface, который будет наследовать AccessCheckerInterface, тогда, учитывая пункт 2, приложение можно будет безболезненно перевести с ACL на RBAC и обратно. Работы там на несколько дней вместе с тестами, а профит очевиден.

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Дизайн RBAC

Сообщение samdark » 2019.10.08, 12:03

Приложение уже использует только AccessCheckerInterface. Выделялся он именно чтобы можно было делать для себя что-то проще, чем RBAC. AuthManagerInterface специфичен для RBAC и для других систем управления доступом не подойдёт.

yiiliveext
Сообщения: 499
Зарегистрирован: 2019.08.13, 01:49

Re: Дизайн RBAC

Сообщение yiiliveext » 2019.10.08, 12:10

samdark писал(а):
2019.10.08, 12:03
Приложение уже использует только AccessCheckerInterface. Выделялся он именно чтобы можно было делать для себя что-то проще, чем RBAC. AuthManagerInterface специфичен для RBAC и для других систем управления доступом не подойдёт.
Я ж не против. Написал "возможно", потому как я пока yii3 смотрю только в пределах кода на гитхаб, могу не знать каких-то нюансов. Если приложение работает с авторизацией исключительно через AccessCheckerInterface - это отлично, спасибо за разъяснение.
Последний раз редактировалось yiiliveext 2019.10.08, 12:23, всего редактировалось 1 раз.

mj4444
Сообщения: 41
Зарегистрирован: 2015.06.08, 19:56

Re: Дизайн RBAC

Сообщение mj4444 » 2019.10.31, 22:16

На счёт ACL. В большинстве случаев штука достаточно специфичная, но можно попробовать реализовать некоторые базовые интерфейсы и некоторый простой вариант для тех кто не хочет заморачиваться над изобретением велосипеда в простой ситуации.

Идеи:
1) Yiisoft\Access\AccessCheckerInterface переименовать в Yiisoft\Access\UserAccessCheckerInterface.
2) Добавить Yiisoft\Access\ACLAccessCheckerInterface и простую его реализацию (по аналогии с RBAC для AccessCheckerInterface)

Код: Выделить всё

interface ACLAccessCheckerInterface
{
    public function aclHasPermission($userId, string $permissionName, $entity, array $parameters = []): bool;
}
Пакет ACL как и RBAC будет иметь разные варианты хранения ACL (отдельная таблица в базе данных, отдельное поле в Entity).
Можно добавить базовый интерфейс ACLEntityInterface для возможности кастомизации проверки ACL для Entity (экземпляры Entity будут реализовывать данный интерфейс, сами реализуя механизм проверки).
К примеру можно добавить документу проверку статуса документа или дефолтные права для какой либо группы пользователей (что бы не размещать их в каждом отдельном документе).

Код: Выделить всё

interface ACLEntityInterface
{
    public function aclHasPermission($userId, string $permissionName,  \Yiisoft\Access\AccessCheckerInterface $accessChecker, array $parameters = []): bool;
}
Все Entity для которых будет осуществляться проверка простым ACL, должны поддерживать интерфейс UniqueEntityInterface или любой другой интерфейс, позволяющий уникально идентифицировать Entity. Возможно данный интерфейс можно реализовывать в какой нибудь ActiveRecord, позволяя полностью сконфигурировать простой ACL внося изменения только в конфигурацию приложения.

Код: Выделить всё

interface UniqueEntityInterface
{
    public function getUniqueId(): string;
}
Можно хранить ACL в Blob поле ActiveRecord у каждой отдельной сущности или создать таблицу связей из 3 полей (entity, subject, permList)
entity - entity->getUniqueId()
subject - (user:$userId|role:$roleName)
permList - сериализованный список permission

Резюме:
Если всё это сделать, мы сможем как в случае с RBAC просто подключить ACL в конфиге и без какого либо лишнего кода проверять доступ к Entity с помощью стандартного менеджера ACL (function aclHasPermission($userId, string $permissionName, $entity, array $parameters = []): bool;).

Аватара пользователя
yiijeka
Сообщения: 3068
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: Дизайн RBAC

Сообщение yiijeka » 2019.11.01, 16:41

@mj4444 нейминг методов всё портит. Если вашу идею изложить с учётом https://github.com/yiisoft/access/pull/3 , то открываются удивительные вещи...

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Дизайн RBAC

Сообщение samdark » 2019.11.02, 01:40

Сигнатуры довольно схожи:

Код: Выделить всё

// RBAC:
public function userHasPermission($userId, string $permissionName, array $parameters = []): bool;

// Ваш интерфейс:
public function aclHasPermission($userId, string $permissionName, $entity, array $parameters = []): bool;
Отличие только в наличии entity. Сейчас мы entity передаём через параметры и вроде нормально.

mj4444
Сообщения: 41
Зарегистрирован: 2015.06.08, 19:56

Re: Дизайн RBAC

Сообщение mj4444 » 2019.11.18, 08:36

yiijeka писал(а):
2019.11.01, 16:41
@mj4444 нейминг методов всё портит. Если вашу идею изложить с учётом https://github.com/yiisoft/access/pull/3 , то открываются удивительные вещи...
Вы не поняли суть идеи. RBAC это одно, а ACL это как дополнительный функционал расширяющий возможности RBAC.
При придумывании имён я как раз и ориентировался на то, на что вы сослались.
Кастомная реализация RBAC и ACL может быть выполнена через один класс, соответственно пересечение имён не очень хорошо.
samdark писал(а):
2019.11.02, 01:40
Сигнатуры довольно схожи:

Отличие только в наличии entity. Сейчас мы entity передаём через параметры и вроде нормально.
Нет, entity не единственное отличие.

Идея на самом деле в следующем:
userHasPermission проверяет доступ через некоторый компонент RBAC (реализация не важна).
aclHasPermission проверяет доступ через компонент ACL. Для работы ACL возможно наличие RBAC будет не обязательным.
Как вы себе представляете разруливать это через один общий интерфейс и метод?

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Дизайн RBAC

Сообщение samdark » 2019.11.18, 15:47

Легко. Спрашиваем "есть ли доступ", передаём объект. А что там внутри нам не важно.

mj4444
Сообщения: 41
Зарегистрирован: 2015.06.08, 19:56

Re: Дизайн RBAC

Сообщение mj4444 » 2019.11.18, 19:50

samdark писал(а):
2019.11.18, 15:47
Легко. Спрашиваем "есть ли доступ", передаём объект. А что там внутри нам не важно.
То есть так понимаю реализацию RBAC вы делать не собираетесь (если что там внутри вам не важно) ?

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Дизайн RBAC

Сообщение samdark » 2019.11.18, 22:13

Уже сделали. Просто есть интерфейс отдельно: https://github.com/yiisoft/access

mj4444
Сообщения: 41
Зарегистрирован: 2015.06.08, 19:56

Re: Дизайн RBAC

Сообщение mj4444 » 2019.11.19, 06:44

samdark писал(а):
2019.11.18, 22:13
Уже сделали. Просто есть интерфейс отдельно: https://github.com/yiisoft/access
Не то написал. Имел ввиду реализацию ACL.

Я так понимаю вы предлагаете реализовывать ACL через Rule из RBAC. Тогда может какие то готовые варианты Rule сделать (сейчас там вижу только один абстрактный базовый класс.

В конечном итоге хотелось бы как и в случае с RBAC:
1) Подключить готовый модуль.
2) С помощью миграции создать базу данных ACL.
3) Нужным сущностям задать интерфейс который позволит этому модулю уникально идентифицировать объект.
4) Выполнять метод userHasPermission с передачей туда объекта для проверки доступа к этому объекту.
5) Иметь возможность управлять списком ACL объектов.
6) Иметь функцию автоматической очистки списка ACL при удалении объекта.

И второй вариант без отдельной таблицы, с таблицей ACL в свойстве объекта.
1) Подключить готовый модуль.
2) Создать всем сущностям текстовое поле для серилизованной таблицы ACL.
3) Выполнять метод userHasPermission с передачей туда объекта для проверки доступа к этому объекту.
4) Иметь возможность управлять списком ACL объектов.

Тогда большинству пользователей не пришлось бы писать свою ACL.

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Дизайн RBAC

Сообщение samdark » 2019.11.19, 11:45

Подумаем над этой темой, но не сразу. Если есть желание, можете попробовать реализовать и сделать pull request.

Ответить