(отказ от ответственности - я работаю в Axiomatics, ведущей реализации XACML и ABAC)
Отличный вопрос. Я фактически составил жизненный цикл политики авторизации, который проводит пользователей через процесс сбора требований, определения атрибутов и реализации политик.
![«Жизненный](https://i.stack.imgur.com/5YK2J.png)
В вашем случае давайте рассмотрим ваши требования
Сбор требований
Ваши первоначальные требования
Должно выполняться любое из следующих утверждений:
- Пользователь должен быть владельцем рецепта (человеком, который его написал).
- Пользователь должен быть членом команды проекта, в котором был создан рецепт. (напрямую или через членство в группе)
- Пользователь должен быть членом группы, производящей рецепт. (Им нужно увидеть рецепт для его изготовления.)
- Пользователь должен быть членом группы, которая разработала рецепт в течение последних двух недель. (то есть после выполнения запроса на изготовление рецепта они могут продолжать просматривать рецепт в течение двух недель, чтобы исправить любые проблемы.)
- Пользователь должен быть администратором.
Реструктуризация требований
Мне нравится переделывать требования как подлежащее - глагол - объект, например. Пользователь может просмотреть рецепт ... На основе этой модели ваши первоначальные требования могут быть переформулированы следующим образом:
- Пользователь может просмотреть рецепт, которым владеет.
- Пользователь может просмотреть рецепт, созданный внутри проекта, к которому он принадлежит.
- Пользователь может просматривать рецепт на стадии производства, который принадлежит к (производственной) группе, к которой принадлежит пользователь.
- Пользователь может просматривать рецепт на стадии изготовления, которая принадлежит к группе (производственной), к которой принадлежит пользователь, и если дата изготовления находится в пределах 2 недель от сегодняшней даты.
- Администраторы могут просматривать рецепты.
Определить атрибуты
Вы можете разбить атрибуты на разные категории (или грамматические функции). XACML сам использует категории, поэтому это естественный шаг к реализации с использованием XACML (или ALFA) .
Атрибуты темы
- userId: ключевой атрибут в этой категории. Он будет использоваться для идентификации пользователя, а также для получения всех других производных атрибутов.
- проект: список проектов, к которым принадлежит пользователь
- группа: список групп, к которым принадлежит пользователь
- роль: роль пользователя, например.
Атрибуты ресурсов
- objectType: это атрибут, который вы используете, чтобы различать разные типы элементов, к которым вы хотите контролировать доступ, например. рецепт, документ или транзакция
- recipeId: ключевой атрибут рецептов. Он будет использоваться для определения того, к какому конкретному рецепту вы хотите получить доступ, а также будет служить ключом для поиска других атрибутов, например. состояние, в котором находится рецепт, группа и проект, к которому он принадлежит.
- группа: группа, к которой принадлежит рецепт
- project: проект, которому принадлежит рецепт
Атрибуты действия
В этой категории, судя по всему, у вас есть только:
- actionId с потенциальными значениями {просмотр, редактирование, удаление ...}.
Требования переписаны с использованием атрибутов
- Любой может выполнить действие == "просмотр" для objectType == "рецепт", если recipe.owner == userId
- Любой может выполнить действие == "просмотр" для objectType == "рецепт", если recipe.project == user.project
- Любой может выполнить действие == "просмотр" для objectType == "рецепт", если recipe.stage == "производство" и recipe.group == user.group.
- Любой может выполнить действие == "просмотр" для objectType == "recipe", если recipe.stage == "made" и recipe.group == user.group и currentDate ‹= recipe.manufacturedDate +" 2 недели ".
- Любой человек с ролью == "администратор" может выполнить действие == "просмотр" для objectType == "рецепт".
Реализация политик с использованием ALFA или XACML
Следующим шагом будет реализация вашей политики. Вы можете использовать ALFA (сокращенный язык для авторизации). Axiomatics имеет плагин Eclipse, который переводит ALFA в XACML 3.0.
Давайте создадим набор политик, который обрабатывает рецепты. Этот набор политик будет содержать политику, которая обрабатывает представление действий. Эта политика, в свою очередь, будет содержать правила, учитывающие каждое требование.
policyset recipe{
target clause objectType == "recipe"
apply firstApplicable
/**
* View recipes
*/
policy viewRecipe{
target clause actionId == "view"
apply firstApplicable
/**
* Administrators can view all recipes
*/
rule administrator{
target clause user.role == "administrator"
permit
}
/**
* Recipe owners can view their own recipes
*/
rule owner{
permit
condition user.userId == recipe.owner
}
/**
* Users can view recipes in their project
*/
rule sameProject{
permit
condition user.assignedProject == recipe.assignedProject
}
/**
* Users can view recipes in their project
*/
rule sameGroup{
target clause recipe.stage == "manufacturing"
permit
condition user.assignedGroup == recipe.assignedGroup
}
/**
* Users can view recipes in their project
*/
rule sameGroupManufactured{
target clause recipe.stage == "manufacturing"
permit
condition user.assignedGroup == recipe.assignedGroup && currentDate<=dateTimeAddDayTimeDuration(dateTimeOneAndOnly(recipe.manufacturedDate),"P14D":dayTimeDuration)
}
}
}
Использование пунктов информации о политике
Как PIP будет собирать эту информацию? Прямо из базы данных? Через служебные вызовы в систему, которая хранит эту информацию?
PIP - это просто абстрактное понятие источника внешнего атрибута. Это может быть что угодно. В разных реализациях будут разные разъемы PIP. Например, сервер политики Axiomatics предоставляет соединители для служб SQL, LDAP и REST. Это покрывает большинство потребностей клиента.
XACML и OAuth 2.0
Вы сравниваете обе технологии, но они чем-то немного отличаются. OAuth 2.0 в первую очередь ориентирован на аутентификацию. Он собирался победить анти-шаблон пароля. Затем возникла необходимость определить разрешения или, как их называют в OAuth, области действия. Однако эти области являются только пунктуальными разрешениями. Вы по-прежнему полагаетесь на то, что целевое приложение публикует набор допустимых областей, и вы по-прежнему не можете выполнять детальный контроль доступа. Мой коллега написал по этой теме блог из трех частей, первую часть которого вы можете прочтите здесь.
Надеюсь, это поможет. Не стесняйтесь задавать уточняющие вопросы или писать мне в Твиттере.
Вывод XACML (бонус)
<?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 xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
PolicySetId="http://axiomatics.com/alfa/identifier/so.recipe"
PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable"
Version="1.0">
<xacml3:Description>Control access to recipes</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">recipe</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.objectType"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Policy xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
PolicyId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
Version="1.0">
<xacml3:Description>View recipes</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="so.actionId"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.administrator">
<xacml3:Description>Administrators can view all recipes</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="so.user.role"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.owner">
<xacml3:Description>Recipe owners can view their own recipes</xacml3:Description>
<xacml3:Target />
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.userId"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.owner"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.sameProject">
<xacml3:Description>Users can view recipes in their project</xacml3:Description>
<xacml3:Target />
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.assignedProject"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.assignedProject"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.sameGroup">
<xacml3:Description>Users can view recipes in their project</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">manufacturing</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.recipe.stage"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/so.recipe.viewRecipe.sameGroupManufactured">
<xacml3:Description>Users can view recipes in their project</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">manufacturing</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="so.recipe.stage"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Match>
</xacml3:AllOf>
</xacml3:AnyOf>
</xacml3:Target>
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of-any">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<xacml3:AttributeDesignator
AttributeId="so.user.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
<xacml3:AttributeDesignator
AttributeId="so.recipe.assignedGroup"
DataType="http://www.w3.org/2001/XMLSchema#string"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than-or-equal"/>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:dateTime-add-dayTimeDuration" >
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only" >
<xacml3:AttributeDesignator
AttributeId="so.recipe.manufacturedDate"
DataType="http://www.w3.org/2001/XMLSchema#dateTime"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"
MustBePresent="false"
/>
</xacml3:Apply>
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#dayTimeDuration">P14D</xacml3:AttributeValue>
</xacml3:Apply>
<xacml3:AttributeDesignator
AttributeId="currentDate"
DataType="http://www.w3.org/2001/XMLSchema#dateTime"
Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
</xacml3:Policy>
</xacml3:PolicySet>
person
David Brossard
schedule
05.01.2017