Подробное понимание работы механизма сопоставления в Casbin
В этой статье объясняется, как п роектировать и реализовывать RBAC с помощью библиотеки Casbin. Для SaaS-платформ с иерархией ресурсов и ролями, наследующими разрешения, Casbin является производительным вариантом.
Введение в RBAC
RBAC ограничивает доступ на основе ролей, которые имеют пользователи. Чтобы понять, как работает иерархический RBAC, мы рассмотрим RBAC Azure, а затем реализуем аналогичную систему в Casbin.
Иерархический RBAC в Azure

В Azure роль Owner применяется на разных уровнях области действия. Если у меня есть права Owner на уровне подписки, я являюсь владельцем всех групп ресурсов и ресурсов в рамках этой подписки. Если у меня есть пр ава Owner на уровне группы ресурсов, я являюсь владельцем всех ресурсов в этой группе.
На изображении ниже показан доступ Owner на уровне подписки. 
Проверка IAM для группы ресурсов в рамках этой подписки показывает унаследованный доступ Owner. 
Так работает иерархическая модель RBAC в Azure. Многие системы используют подобные иерархии. В этом руководстве мы реализуем аналогичную модель с помощью Casbin.
Как работает Casbin
Понимание основных компонентов Casbin (запрос, политика, матчер, эффект) облегчает проектирование и настройку вашей модели RBAC.
Что такое ACL?
ACL (Access Control List) связывает пользователей с действиями, а действия — с ресурсами.
Определение модели
Минимальная модель ACL:
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
- request_definition — Определяет формат запроса. Например,
alice, write, data1означает «Может ли Alice записать данные в data1?» - policy_definition — Определяет формат политики. Например, политика
alice, write, data1предоставляет Alice разрешение на запись данных в data1. - policy_effect — Способ объединения нескольких совпавших политик (например, allow-override).
- matchers — Условие, которое должно выполняться:
r.sub == p.sub && r.obj == p.obj && r.act == p.act.
Попробуйте в редакторе Casbin
Откройте редактор Casbin и вставьте приведенную выше модель в редактор Model.
Вставьте следующее в редактор Policy:
p, alice, read, data1
p, bob, write, data2
и следующее в редактор Request:
alice, read, data1
Результат будет следующим:
true
Визуальное представление модели ACL, политики и сопоставления запроса

Что такое RBAC?
RBAC (Role-Based Access Control) назначает пользователям роли; роли имеют разрешения на ресурсы. Запрос проверяет, позволяет ли роль пользователя выполнить действие над ресурсом.
Определение модели
Простая модель RBAC:
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[role_definition]
g = _, _
g2 = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && g(p.act, r.act) && r.obj == p.obj
- role_definition — Определяет графовые отношения (например,
gдля связей «роль–роль» или «пользователь–роль»). Матчер использует их для определения ролей и разрешений.
Попробуйте в редакторе Casbin
Откройте редактор и вставьте приведенную выше модель.
Вставьте следующее в редактор Policy:
p, alice, reader, data1
p, bob, owner, data2
g, reader, read
g, owner, read
g, owner, write
и следующее в редактор Request:
alice, read, data1
alice, write, data1
bob, write, data2
bob, read, data2
bob, write, data1
Результат будет следующим:
true
false
true
true
false
Визуальное представление модели RBAC, политики и сопоставления запроса

Отношение g (связь между ролями и действиями) представляет собой граф. В политике оно записывается в виде ребер, например:
g, reader, read
g, owner, read
g, owner, write
p — это обычная политика (сравнивается через ==). g — это графовое отношение. Вы можете добавить больше отношений с суффиксами: g2, g3 и т. д.
Иерархический RBAC
В иерархическом RBAC существует несколько типов ресурсов с наследованием (например, Подписка → Группа ресурсов). Подписка sub1 может содержать группы ресурсов rg1, rg2. Аналогично существуют роли/действия на уровне подписки и на уровне группы ресурсов, с наследованием между ними. Например, роль подписки sub-owner может наследоваться к роли группы ресурсов rg-owner: если у меня есть sub-owner на sub1, то фактически у меня есть rg-owner на rg1 и rg2.
Определение модели
Минимальная модель иерархического RBAC:
[request_definition]
r = sub, act, obj
[policy_definition]
p = sub, act, obj
[role_definition]
g = _, _
g2 = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && g(p.act, r.act) && g2(p.obj, r.obj)
Здесь g связывает роли/действия, а g2 связывает ресурсы (например, подписку с группой ресурсов).
Попробуйте в редакторе Casbin
Откройте редактор и вставьте модель выше.
Вставьте следующее в редактор Policy:
p, alice, sub-reader, sub1
p, bob, rg-owner, rg2
// subscription role to subscription action mapping
g, sub-reader, sub-read
g, sub-owner, sub-read
g, sub-owner, sub-write
// resourceGroup role to resourceGroup action mapping
g, rg-reader, rg-read
g, rg-owner, rg-read
g, rg-owner, rg-write
// subscription role to resourceGroup role mapping
g, sub-reader, rg-reader
g, sub-owner, rg-owner
// subscription resource to resourceGroup resource mapping
g2, sub1, rg1
g2, sub2, rg2
И вставьте следующее в редактор Request:
alice, rg-read, rg1
Результат будет таким:
true
Визуальное представление совпадения модели RBAC, политики и запроса

Ребра g (роль → действие, роль → роль) могут быть записаны в политике как:
// subscription role to subscription action mapping
g, sub-reader, sub-read
g, sub-owner, sub-read
g, sub-owner, sub-write
// resourceGroup role to resourceGroup action mapping
g, rg-reader, rg-read
g, rg-owner, rg-read
g, rg-owner, rg-write
// subscription role to resourceGroup role mapping
g, sub-reader, rg-reader
g, sub-owner, rg-owner
Ребра g2 сопоставляют подписку с группой ресурсов:
// subscription resource to resourceGroup resource mapping
g2, sub1, rg1
g2, sub2, rg2
Совпадение субъекта: визуальное представление

Совпадение действия: визуальное представление

Совпадение объекта: визуальное представление

Casbin проверяет запрос по всем политикам. Если хотя бы одна политика совпадает, результат — true; иначе — false.
Заключение
В этом руководстве показано, как ACL, RBAC и иерархический RBAC можно выразить в Casbin. В следующей части мы реализуем это в приложении на Spring Boot и защитим API с помощью Casbin.

Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.