RBAC/ABAC через политики XACML
Я изучаю различные типы моделей контроля доступа и узнал, что abac и rbac являются популярными.
У меня есть базовый сценарий для одного из моих проектов, и я не мог понять, должен ли я пойти с RBAC
или же ABAC
, очевидно RBAC
является подмножеством ABAC
так что определенно я должен пойти на ABAC
но ABAC требует некоторого опыта для написания политик в xacml. Мы используем WSO
ЕСТЬ и APIM.
У меня есть роли администратора, владельца и члена на моем сервере идентификации (IS).
- Администратор может просматривать, удалять и обновлять пользователей.
- Владельцы могут просматривать и обновлять.
- Пользователи могут только просматривать.
На данный момент я использую HTTP
глаголы для достижения желаемого результата, т.е. владельцы не могут получить доступ DELETE
запросы и участники не могут получить доступ PUT
& DELETE
,
проблема
У меня есть панель инструментов, где я показываю различные разделы, такие как топ-пользователи, биллинг, сервисы, топ-потребители и т. Д.
- Мне нужно заселить
nav-bar
на основе роли пользователя и атрибутов с сервера, например, участники не должны иметь доступа, чтобы видеть других пользователей (Добавить, Список) вnav-bar
,nav-bar
элементы зависят от роли пользователя, поэтому мы можем управлять ими черезRBAC
? - У нас есть план по добавлению ролей, таких как ops, маркетинг, поддержка и т. Д. Означает ли это, что нам нужно создать отдельную db-схему для поддержки прав доступа для каждой роли?
- В инструментальной панели мне нужно скрыть / показать вид, обновить и удалить кнопки в пользователях, сервисах и т. Д. Теперь участники могут видеть пользователей, но не имеют разрешения на их обновление или удаление. Не может просматривать статистику, биллинг и другую личную информацию.
- Владельцы могут видеть всех пользователей, связанных с их отделами / организацией, но Администратор может видеть всех пользователей для всех отделов / организаций. Здесь нам нужно использовать один и тот же API для всех потребителей, но API должен реагировать по-разному для разных ролей. Роли могут быть 10 и 100, поэтому они не могут создавать разные API для каждой роли.
Вопрос
Мы можем реализовать все эти сценарии с помощью RBAC
но для управления nav-bar
и просмотрите соответствующую реализацию, нам нужно добавить бизнес-логику на наш сервер вместо использования WSO2-IS
а также WSO2-APIM
, Есть ли способ управлять разрешениями на просмотр, такими как скрытие / отображение кнопок и разделов, и даже потреблять их? API
но он должен возвращать разные результаты для разных API-потребителей.
2 ответа
Прежде всего мои извинения за поздний ответ. Вот мои комментарии в строке.
ACL, RBAC, ABAC
Я изучаю различные типы моделей контроля доступа и узнал, что abac и rbac являются популярными.
Исторически контроль доступа осуществлялся через списки контроля доступа (ACL), затем контроль доступа на основе ролей (RBAC) и контроль доступа на основе атрибутов (ABAC). Списки ACL стали громоздкими и сложными в управлении, поэтому NIST разработал RBAC в 1992 году (да, он такой старый). RBAC хорошо известен, зрел и встроен в большинство продуктов и приложений IAM. Например, пользовательский каталог (LDAP, AD...) поддерживает назначения пользователей и ролей и предоставляет приложениям те роли, которые приложение затем может использовать для определения необходимости предоставления доступа. С RBAC более детальный доступ (например, доступ, основанный на отношениях, как в вашем случае, когда пользователь может видеть только свои собственные данные) невозможен, поэтому либо (а) разработчик приложения пишет собственный код для получения правильного доступа, либо (б) вы используйте ABAC.
Почему ABAC?
ABAC дает вам возможность определять детализированный доступ на основе любого типа атрибута (не только роли и не только пользовательских атрибутов), используя политики для описания того, что может (или не может) происходить. ABAC иногда называют PBAC (управление доступом на основе политик). Вы ссылаетесь на XACML, который является языком, на котором реализуются политики ABAC. Вы также можете взглянуть на alfa ( Wikipedia), более простой язык, который отображается непосредственно в XACML.
ABAC также определяет архитектуру с идеей точки принятия решений (PDP), которая обрабатывает ваши запросы на авторизацию в соответствии с политиками, с которыми она была настроена. PDP (в вашем случае WSO2 Balana часть WSO2 IS) вызывается из точки реализации политики (PEP), такой как ваше приложение или что-то, находящееся перед вашим приложением (например, шлюз API или перехватчик в вашем случае WSO2 API Manager).
Ваш вариант использования
У меня есть базовый сценарий для одного из моих проектов, и я не мог понять, должен ли я пойти с RBACor ABAC. Очевидно, что RBAC является подмножеством ABAC, так что определенно я должен пойти на ABAC, но ABAC требуется некоторый опыт для написания политик в xacml. Мы используем WSO IS и APIM.
Я бы не сказал, что RBAC является подмножеством ABAC. Это действительно с точки зрения функциональности. Но это не одно против другого. ABAC расширит RBAC, введя больше атрибутов, политик и вышеупомянутой архитектуры.
У меня есть роли администратора, владельца и члена на моем сервере идентификации (IS).
- Администратор может просматривать, удалять и обновлять пользователей.
- Владельцы могут просматривать и обновлять.
- Пользователи могут только просматривать.
Это замечательно. То, что вы делаете, это определение ваших требований авторизации. Они будут сопоставлены непосредственно с вашими политиками ALFA / XACML.
В данный момент я использую HTTP-глаголы для достижения желаемых результатов, то есть владельцы не могут получить доступ к запросам DELETE, а участники не могут получить доступ к PUT & DELETE.
В ABAC мы также используем действия. Это могут быть простые старые человеческие действия (просмотр, редактирование, удаление, утверждение...), которые затем могут быть сопоставлены с глаголами HTTP.
Ваш вызов
В приведенном ниже тексте я выделил жирным шрифтом то, что я считаю вашими дополнительными требованиями к авторизации.
У меня есть панель инструментов, где я показываю различные разделы, такие как топ-пользователи, биллинг, сервисы, топ-потребители и т. Д.
Мне нужно заполнить панель навигации на основе роли пользователя и атрибутов с сервера, например, участники не должны иметь доступа, чтобы видеть других пользователей (Добавить, Список) в панели навигации. Элементы навигационной панели зависят от роли пользователя, поэтому мы можем управлять ими через RBAC?
Это будет обработано с помощью политики ABAC. Увидеть ниже
У нас есть план по добавлению ролей, таких как ops, маркетинг, поддержка и т. Д. Означает ли это, что нам нужно создать отдельную db-схему для поддержки прав доступа для каждой роли?
Нет! Вам не нужно создавать новые схемы БД, не говоря уже о том, чтобы поддерживать права доступа в пользовательских системах. Используйте политику, чтобы сделать это.
В инструментальной панели мне нужно скрыть / показать вид, обновить и удалить кнопки в пользователях, сервисах и т. Д. Теперь участники могут видеть пользователей, но не имеют разрешения на их обновление или удаление. Они не могут просматривать статистику, выставление счетов и другую личную информацию.
Владельцы могут видеть всех пользователей, связанных с их отделами / организацией, но Администратор может видеть всех пользователей для всех отделов / организаций. Здесь нам нужно использовать один и тот же API для всех потребителей, но API должен по-разному реагировать на разные роли. Роли могут быть 10 и 100, поэтому они не могут создавать разные API для каждой роли. Вопрос
Мы можем реализовать все эти сценарии через RBAC, но для управления навигационной панелью и просмотра связанной реализации нам нужно добавить бизнес-логику на нашем сервере вместо использования WSO2-IS и WSO2-APIM. Есть ли способ управлять разрешениями на просмотр, такими как кнопки и секции скрытия / показа, и даже использовать один и тот же API, но он должен возвращать разные результаты для разных потребителей API.
Определенно да. Это цель использования ABAC и политик. Учитывая, что вы используете WSO2 IS, посмотрите на Balana, PDP внутри этого продукта. Есть и другие решения, например, AuthZForce (с открытым исходным кодом) или Axiomatics (там, где я работаю)
Решение
Вот пример политики, написанной на ALFA и переводе XACML ниже
namespace haris {
/**
* User Records
*/
policyset users {
target clause axiomatics.objectType == "user record"
apply firstApplicable
/**
* View user record
*/
policy viewUser {
target clause axiomatics.actionId == "view" // This can be the HTTP verb
apply firstApplicable
/**
* Administrators can view all users
*/
rule administrator{
target clause axiomatics.user.role == "administrator"
permit
}
/**
* Owners can view users in their department
*/
rule owners{
target clause axiomatics.user.role == "owner"
permit
condition axiomatics.user.department == axiomatics.record.department
}
/**
* Members can view their own user record only
*/
rule member{
permit
condition axiomatics.user.username == axiomatics.record.owner
}
}
/**
* Update user
*/
policy updateUser {
target clause axiomatics.actionId == "update" // This can be the HTTP verb
apply firstApplicable
/**
* Administrator can update any user
*/
rule administrator{
target clause axiomatics.user.role == "administrator"
permit
}
/**
* Owner can update any user
*/
rule owner{
target clause axiomatics.user.role == "owner"
permit
// TODO: determine what an owner can update
}
}
/**
* Delete user
*/
policy deleteUser {
target clause axiomatics.actionId == "delete" // This can be the HTTP verb
apply firstApplicable
/**
* Administrator can delete any user
*/
rule administrator{
target clause axiomatics.user.role == "administrator"
permit
}
}
}
}
И версия XML
<?xml version="1.0" encoding="UTF-8"?><!--This file was generated by the
ALFA Plugin for Eclipse from Axiomatics AB (http://www.axiomatics.com). --><!--Any modification to this file will
be lost upon recompilation of the source ALFA file -->
<xacml3:PolicySet
PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable"
PolicySetId="http://axiomatics.com/alfa/identifier/haris.users"
Version="1.0"
xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17">
<xacml3:Description>User Records</xacml3:Description>
<xacml3:PolicySetDefaults>
<xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116
</xacml3:XPathVersion>
</xacml3:PolicySetDefaults>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">user record</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="axiomatics.objectType"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Policy
PolicyId="http://axiomatics.com/alfa/identifier/haris.users.viewUser"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
Version="1.0">
<xacml3:Description>View user record</xacml3:Description>
<xacml3:PolicyDefaults>
<xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116
</xacml3:XPathVersion>
</xacml3:PolicyDefaults>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">view</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="axiomatics.actionId"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Rule Effect="Permit"
RuleId="haris.users.viewUser.administrator">
<xacml3:Description>Administrators can view all users
</xacml3:Description>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">administrator</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="axiomatics.user.role"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
</xacml3:Rule>
<xacml3:Rule Effect="Permit"
RuleId="haris.users.viewUser.owners">
<xacml3:Description>Owners can view users in their department
</xacml3:Description>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">owner</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="axiomatics.user.role"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Condition>
<xacml3:Apply
FunctionId="urn:oasis:names:tc:xacml:3.0:function:any-of-any">
<xacml3:Function
FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal" />
<xacml3:AttributeDesignator
AttributeId="axiomatics.user.department"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
<xacml3:AttributeDesignator
AttributeId="axiomatics.record.department"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
<xacml3:Rule Effect="Permit"
RuleId="haris.users.viewUser.member">
<xacml3:Description>Members can view their own user record only
</xacml3:Description>
<xacml3:Target />
<xacml3:Condition>
<xacml3:Apply
FunctionId="urn:oasis:names:tc:xacml:3.0:function:any-of-any">
<xacml3:Function
FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal" />
<xacml3:AttributeDesignator
AttributeId="axiomatics.user.username"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
<xacml3:AttributeDesignator
AttributeId="axiomatics.record.owner"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
</xacml3:Policy>
<xacml3:Policy
PolicyId="http://axiomatics.com/alfa/identifier/haris.users.updateUser"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
Version="1.0">
<xacml3:Description>Update user</xacml3:Description>
<xacml3:PolicyDefaults>
<xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116
</xacml3:XPathVersion>
</xacml3:PolicyDefaults>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">update</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="axiomatics.actionId"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Rule Effect="Permit"
RuleId="haris.users.updateUser.administrator">
<xacml3:Description>Administrator can update any user
</xacml3:Description>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">administrator</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="axiomatics.user.role"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
</xacml3:Rule>
<xacml3:Rule Effect="Permit"
RuleId="haris.users.updateUser.owner">
<xacml3:Description>Owner can update any user</xacml3:Description>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">owner</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="axiomatics.user.role"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
</xacml3:Rule>
</xacml3:Policy>
<xacml3:Policy
PolicyId="http://axiomatics.com/alfa/identifier/haris.users.deleteUser"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
Version="1.0">
<xacml3:Description>Delete user</xacml3:Description>
<xacml3:PolicyDefaults>
<xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116
</xacml3:XPathVersion>
</xacml3:PolicyDefaults>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">delete</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="axiomatics.actionId"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Rule Effect="Permit"
RuleId="haris.users.deleteUser.administrator">
<xacml3:Description>Administrator can delete any user
</xacml3:Description>
<xacml3:Target>
<xacml3:AnyOf>
<xacml3:AllOf>
<xacml3:Match
MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#string">administrator</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="axiomatics.user.role"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="false" />
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
</xacml3:Rule>
</xacml3:Policy>
</xacml3:PolicySet>
Применение политик
Как я буду возвращать разные данные для одного API, но для разных ролей / пользователей.
Предположим, у вас есть API, например /api/profiles/{profileID}
, Есть 2 способа использования API:
- GET /api/ profile возвращает все профили, на которые пользователь имеет право
- GET /api/ Profiles/123 вернет профиль 123, если пользователь имеет право или HTTP 403 в противном случае (или 404 - вы можете утверждать, что вы даже не хотите показывать, что указанный профиль существует).
Для этого вам необходимо внедрить Point Enforcement Point (PEP). Это может быть API-менеджер WSO2. ПКП несет ответственность за
- парсинг входящего вызова API (GET /api/profile/123)
- преобразование его в запрос авторизации, например, может ли Алиса просмотреть профиль 123?
- отправка запроса в PDP
- обработка ответа, полученного обратно от PDP, и, в частности, извлечение решения (например, разрешения).
Если решение является разрешением, то вызов перенаправляется в ваш внутренний API. Если это не так, вы можете вернуть HTTP 403 / 404, как обсуждалось.
Если это 403, то вызов переходит к бэкэнду, и в конечном итоге ответ переходит от вашего бэкэнда и проходит через PEP, где он может еще раз вызвать PDP, например, чтобы отредактировать данные.
Нужно ли включать в мой бизнес-логику, такую как получение элементов навигационной панели, получение статистики использования API, полный доступ к данным для администраторов и организации / отдела для владельцев и ограниченные данные для членов. Как выполнить эти основные операции?
Нет, ты не При создании меню или элементов навигации вы также можете вызвать PDP и спросить, может ли данный пользователь получить доступ к заданному набору функций, например, "Может ли Алиса просмотреть элемент панели навигации № 123?". Вам нужна минимальная бизнес-логика для вызова PDP.
После некоторого наблюдения я могу думать об одном.
- https: // локальный: 9443 / API / ч / издатель / v0.13 / APIs предел = 25 & смещение = 0
- https: // локальный: 9443 / API / ч / магазин / v0.13 / подписка apiId = APP_ID
- https: // локальный: 9443 / API / ч / издатель / v0.13 / APIs / sub_id
Используйте выше WSO2 APIM
API, чтобы получить swagger.json
для данного API
(они должны / будут иметь все доступные API). Теперь используйте соответствующие HTTP-verbs
сопоставлять ресурсы с ролями и ответом.
Например, если участники не должны иметь доступ к DELETE
затем, используя этот подход, мы можем попросить сервер вернуть все разрешения для текущей страницы / просмотра и сопоставить эти значения во внешнем интерфейсе, чтобы скрыть / показать кнопку / просмотры или весь контент.
Недостаток: чтобы избежать дублирования и повторения, мы можем сохранить это отображение в нашей базе данных. Но эта логика требует некоторой бизнес-логики на вашем собственном сервере и доступа к операциям чтения / записи базы данных.