OBAC, несомненно, велосипед по сравнению с Сasbin, которая по сути, сейчас стандарт де-факто для атрибутированного контроля доступа в опенсорсе.
Имеет ли смысл решать ту же задачу по-другому и делать генератор эффективных полномочий или на Сasbin можно сделать все то же самое и даже лучше - это хороший вопрос.
Насчет померять производительность - я планирую сделать бенчмарк OBAC-а, на каком-нибудь не самом тривиальном случае, навроде такого:
5 уровней в иерархии объектов
5 типов проверяемых полномочий
5 записей ACL на каждый уровень, с назначением доступа пользователям и группам
запретительные и разрешительные полномочия. Тут не знаю, как будет правильно, но как идея, для каждого из 5 типов полномочия в цепочке наследования должны попадаться
1 назначение через юзера (allow)
1 назначение через группу (allow)
1 назначение через юзера (deny)
1 назначение через группу (deny)
кол-во объектов значимое, например по 10000 в узле нижнего уровня, на каждом уровне по 2 sibling-a (то есть узлов 2/4/8/16 узлов на уровнях 1-4 и 160тысяч объектов нижнего уровня)
10 000 пользователей и 50 групп по 500 пользователей в каждой
и собственно предмет исследования - оконная функция (сортировка+пейджинг) по узлам нижнего уровня.
В случае OBAC очевидно, что скорость сортировки и пейджинга будет эквивалентна одному дополнительному джоину (см мой пример выше), основные ресурсы будут тратиться в момент заполнения ACL, вычисления и сохранения эффективных полномочий.
В случае Casbin/PERM, попробую применить ваши методики. Самому интересно, что получится.
Мы для себя сделали вывод, что применять Casbin для защиты многих тысяч сущностей, которые создаются в ходе работы системы, не очень себе идея - как раз потому, что нет ясного подхода по работе с эффективными полномочиями. То есть декларативный подход и PERM прекрасны для случая, когда знаешь, какие сущности надо защитить (и как они будут связаны), еще в ходе разработки, а не на момент эксплуатации.
А когда у тебя дерево например объектов, которые создал пользователь, доступ на которые раздали в рантайме, то лучше старые добрые ACL.
В результате была написана библиотека Redberries OBAC (https://github.com/redberriespro/Redb.OBAC), суть которой - раздавать права на иерархические структуры объектов и вычислять для каждого объекта иерархии эффективные полномочия. Посчитанные полномочия можно запросить у библиотеки, а можно и принять в прикладной код специальным ресивером и положить например в БД.
В результате, получение списков из БД с одновременным применением проверки доступа выглядит как-то так:
var docs = from d in ctx.Documents
join p in ctx.EffectivePermissions
on d.Id equals p.ObjectId
where
p.UserId == userId && p.PermissionId == PERM_READ
select d;
В разделах "что гуглить" мне лично не хватает оригинальных названий терминов. Каналы — это channels? Глупые компоненты — silly? dumb? stupid? Нестандартные компоненты — non-standard? custom?
Поскольку статья рассчитана на неопытного пользователя ангуляра, это не очевидно.
Есть некоторое пересечение с аугментацией — расширении обучающего датасета на задачах класса Machine Learning. Тоже берется небольшое количество данных и увеличивается. Например изображение котика масштабируется, сдвигается, другим способом корежится — и соответственно меняется описание того, что в данном элементе датасета (размеры объекта в Kitti-файле для задач Computer Vision)
Согласен про бизнес-логику, но в этом месте статьи я изящно (смайлик) показал способ быстро захардкодить странное. А за странным бизнес иногда прибегает в пятницу вечером со словами что "все забыли, сорян, но в субботу оно должно работать, потому что Урюпинск с утра будет на федеральных каналах". Дописывать ядро бизнес-логики и выкатывать на прод в пятницу не всегда хочется, поэтому можно например вот так, по-простому. С одновременным постом в трекер задачи на техдолг.
Я не пропагандирую какой-то конкретный шаблонизатор, но да, склоняюсь к минимизации логики внутри шаблонов (форматтеры и предикаты по спискам — ОК, выполнение произвольного кода — не ОК). Шаблонизирование через format хорошо, если в модели нет массивов и условий (то есть для ряда случаев — вполне себе метод).
Ну и скорее статья дискутирует с методом, когда подобные артефакты создаются путем конкатенации строчек внутри кода. Такой подход я встречал неоднократно (особенно почему-то любят так мучать SQL). Результат — очень мутный код.
Для сравнения — добавил в гитхабе в template_3.py класс, который формирует SQL путем конкатенации строк по той же модельке. Довольно мутная штука в плане наглядности:
class SqlAntipattern(object):
def render(self, m):
if m["typeList"]:
return self.render_typelist(m)
if m["typeCountGroupBy"]:
return self.render_groupby(m)
raise Exception("Unknown query type")
def render_where(self, m):
sql = "WHERE "
def eqtion(w):
return "{}={}{}{}".format(
w["field"],
"'" if "quot" in w else "",
w["eq_val"],
"'" if "quot" in w else "")
wheres = [eqtion(w) for w in m["where"]]
sql += ", ".join(wheres)
return sql + " "
def render_orderby(self, m):
return "ORDER BY " + m["orderBy"]
def render_typelist(self, m):
sql = "SELECT * FROM " + m["tableName"] + " "
if "hasWhere" in m:
sql += self.render_where(m)
if "orderBy" in m:
sql += self.render_orderby(m)
if "limit" in m:
sql += " LIMIT " + m["limit"]
return sql
def render_groupby(self, m):
sql = "SELECT " + m["groupColumn"]
sql += ", COUNT(*) FROM " + m["tableName"] + " "
sql += " GROUP BY " + m["groupColumn"]
return sql
OBAC, несомненно, велосипед по сравнению с Сasbin, которая по сути, сейчас стандарт де-факто для атрибутированного контроля доступа в опенсорсе.
Имеет ли смысл решать ту же задачу по-другому и делать генератор эффективных полномочий или на Сasbin можно сделать все то же самое и даже лучше - это хороший вопрос.
Точнее даже три вопроса:
Производительность назначения прав ACL
Производительность проверки эффективных полномочий
Удобство использования
Насчет померять производительность - я планирую сделать бенчмарк OBAC-а, на каком-нибудь не самом тривиальном случае, навроде такого:
5 уровней в иерархии объектов
5 типов проверяемых полномочий
5 записей ACL на каждый уровень, с назначением доступа пользователям и группам
запретительные и разрешительные полномочия. Тут не знаю, как будет правильно, но как идея, для каждого из 5 типов полномочия в цепочке наследования должны попадаться
1 назначение через юзера (allow)
1 назначение через группу (allow)
1 назначение через юзера (deny)
1 назначение через группу (deny)
кол-во объектов значимое, например по 10000 в узле нижнего уровня, на каждом уровне по 2 sibling-a (то есть узлов 2/4/8/16 узлов на уровнях 1-4 и 160тысяч объектов нижнего уровня)
10 000 пользователей и 50 групп по 500 пользователей в каждой
и собственно предмет исследования - оконная функция (сортировка+пейджинг) по узлам нижнего уровня.
В случае OBAC очевидно, что скорость сортировки и пейджинга будет эквивалентна одному дополнительному джоину (см мой пример выше), основные ресурсы будут тратиться в момент заполнения ACL, вычисления и сохранения эффективных полномочий.
В случае Casbin/PERM, попробую применить ваши методики.
Самому интересно, что получится.
Мы для себя сделали вывод, что применять Casbin для защиты многих тысяч сущностей, которые создаются в ходе работы системы, не очень себе идея - как раз потому, что нет ясного подхода по работе с эффективными полномочиями. То есть декларативный подход и PERM прекрасны для случая, когда знаешь, какие сущности надо защитить (и как они будут связаны), еще в ходе разработки, а не на момент эксплуатации.
А когда у тебя дерево например объектов, которые создал пользователь, доступ на которые раздали в рантайме, то лучше старые добрые ACL.
В результате была написана библиотека Redberries OBAC (https://github.com/redberriespro/Redb.OBAC), суть которой - раздавать права на иерархические структуры объектов и вычислять для каждого объекта иерархии эффективные полномочия. Посчитанные полномочия можно запросить у библиотеки, а можно и принять в прикладной код специальным ресивером и положить например в БД.
В результате, получение списков из БД с одновременным применением проверки доступа выглядит как-то так:
Пример на C# и Entity Framework, вот тут весь он: https://github.com/redberriespro/Redb.OBAC/blob/main/Examples/HelloObacEf/Program.cs
Спасибо за перевод.
В разделах "что гуглить" мне лично не хватает оригинальных названий терминов. Каналы — это channels? Глупые компоненты — silly? dumb? stupid? Нестандартные компоненты — non-standard? custom?
Поскольку статья рассчитана на неопытного пользователя ангуляра, это не очевидно.
Есть некоторое пересечение с аугментацией — расширении обучающего датасета на задачах класса Machine Learning. Тоже берется небольшое количество данных и увеличивается. Например изображение котика масштабируется, сдвигается, другим способом корежится — и соответственно меняется описание того, что в данном элементе датасета (размеры объекта в Kitti-файле для задач Computer Vision)
Согласен про бизнес-логику, но в этом месте статьи я изящно (смайлик) показал способ быстро захардкодить странное. А за странным бизнес иногда прибегает в пятницу вечером со словами что "все забыли, сорян, но в субботу оно должно работать, потому что Урюпинск с утра будет на федеральных каналах". Дописывать ядро бизнес-логики и выкатывать на прод в пятницу не всегда хочется, поэтому можно например вот так, по-простому. С одновременным постом в трекер задачи на техдолг.
(здесь был ответ на комментарий про бизнес-логику, который потом перенес в правильную ветку)
Я не пропагандирую какой-то конкретный шаблонизатор, но да, склоняюсь к минимизации логики внутри шаблонов (форматтеры и предикаты по спискам — ОК, выполнение произвольного кода — не ОК). Шаблонизирование через format хорошо, если в модели нет массивов и условий (то есть для ряда случаев — вполне себе метод).
Ну и скорее статья дискутирует с методом, когда подобные артефакты создаются путем конкатенации строчек внутри кода. Такой подход я встречал неоднократно (особенно почему-то любят так мучать SQL). Результат — очень мутный код.
Для сравнения — добавил в гитхабе в template_3.py класс, который формирует SQL путем конкатенации строк по той же модельке. Довольно мутная штука в плане наглядности: