Как реализовать фильтрацию списочных эндпоинтов для микросервисов на основе роли пользователя?
Уже есть микросервисы, есть необходимость реализовать более сложную ролевую модель для разграничения доступов. Нужны row based permissions.
Очень не хочется, чтобы права и ролевая модель сильно протекала в каждый из микросервисов. Будет бардак, но по другому вообще не получается придумать.
Если для одной сущности все просто - берем какой-нибудь open policy agent или ory/keto, у них есть удобные правила, подсовываем им объект и они решают можно его смотреть текущему пользователю или нельзя.
А вот со списочными вообще никак, ну не будешь же поднимать в память все сущности и проверять каждый. Или будешь? А как решить проблему пагинации? Что сервис отдал десяток объектов, и они все отфильтровались на policy decision point?
Значит все-таки роли и атрибуты должны "протечь" в каждый микросервис? Но тогда вообще теряется смысл в отдельном микросервисе для централизованных системах прав.
Не понимаю, как это реализуется в микросервисах. В монолите я делал такое, и там все просто - пилишь небольшое расширение для орм, автоматом добавляешь к моделям атрибуты и все магически фильтруется.
В общем случае все решается через ABAC. Что же касается списочных элементов то надо понимать несколько моментов:
- какая цель разграничения
- какая организация ресурсов
По моему опыту в большинстве случаев пробуют подменить организацию ресурсов - системой прав доступа. Надо понимать что это независимые, но часто последовательные процессы.
Возьмём пример - пользователи и проекты в jira. Права описывают доступ к проекту, но никак не влияют на список проектов. Вместо этого в jira хранится ассоциации между проектами и пользователями.
Можно рассмотреть также древовидную структуру ресурсов где права могут разделяться по маске, например:
/resource_type/resource_group/random_prefix*
>- какая цель разграничения
Бизнесовая. Кто-то должен видеть любые публичные ресурсы, кто-то только явно разрешенные.
> - какая организация ресурсов
Не понял.
>Можно рассмотреть также древовидную структуру ресурсов где права могут разделяться по маске, например:
Разве это не есть протекание ролевой модели? Что добавить префикс, что докинуть параметр role=some_role. Суть одинаковое, только под другим именем.
> Вместо этого в jira хранится ассоциации между проектами и пользователями.
Это... При создании пользователя, сразу создавать связи для него? И потом показывать объекты по наличии связей? Я думал о таком, но как-то сложно выходит обработка при смене ролей, неочевидна обратботка при создании новых ресурсов.
Бизнесовая. Кто-то должен видеть любые публичные ресурсы, кто-то только явно разрешенные.
Это несколько не так. Бизнес не получит никакой ценности от этого. По крайней мере прямой. Но при ее реализации он не получит негативного эффекта
Не понял.
Организация ресурсов это отношения данных ресурсов друг-к-другу. В базововом примере это иерархия: если ресурс вложенный то к нему прменяются все те же правила что и для родителя:
Правила:
Grant /author/1/books
Grant /author/1/books/1
Grant /author/1/books/2
эквивалентны (если там всего 2 книги):
Grant /author/1/books*
Но не эквивалентны:
Grant /author/1/*
Разве это не есть протекание ролевой модели?
Нет, ролевая модель учитывает только роли и типы ресурсов. Отдельные ресурсы существуют только в концепции ABAC. Иначе придется добавлять роль на каждый ресурс. Я уже видео организации, которые на этом закончились
При создании пользователя, сразу создавать связи для него?
Зависит от случая, но в общем понимании надо разделять логику приложения и логику предоставления прав. Если использовать DDD то за действием:
- добавить пользователя 1 в группу 2
внутри приложения происходит 2 операции:
- создание связи между ресурсами "пользователь 1" и "группа 2"
- Grant доступов "пользователя 1" на операции над ресурсом "группа 2"
Я думал о таком, но как-то сложно выходит обработка при смене ролей, неочевидна обратботка при создании новых ресурсов.
При должном уровне изоляции - не сложнее чем чихнуть