# Базовые понятия

Доступ пользователей к **Webim** реализован при помощи подхода [Attribute-based access control (ABAC)](https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B7%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%B0_%D0%BD%D0%B0_%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%B5_%D0%B0%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D0%BE%D0%B2), базируемом на атрибутах действий, объектов и т.п. В системе, использующей **ABAC**, разграничение прав доступа выполняется согласно решениям, которое принимает дерево политик на основе вычисления логических выражений для проверки атрибутов. Таким образом, доступы пользователя не привязаны просто к одной из существующих в системе ролей, а могут настраиваться гибко, посредством [Редактора политик](https://webim.ru/kb/for-admins/service-pages/policies-editor.html). **Редактор политик** частично использует понятия и систему выражений **XACML 3.0**, подробные описания которых присутствуют в данной статье, а также в статье о [выражениях](https://webim.ru/kb/for-admins/access-control-system/expressions.html).

Политики, определяющие возможности той или иной роли, задаются при помощи **дерева политик (Policy tree)**.

Реализация проверки доступа на основе атрибутов предполагается концептуально совместимой со стандартом [XACML 3.0](http://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-os-en.html). Рекомендуется ознакомиться с [терминологией стандарта](http://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-os-en.html#_Toc325047068) и секцией [Policy language model](http://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-os-en.html#_Toc325047091).

Решение о доступе (разрешить или запретить) принимается на основе **Дерева политик**. Дерево политик составляется из трех основных элементов: **Правило (Rule)**, **Политика (Policy)** и **Группа политик (PolicySet)**. Каждый из элементов дерева имеет связанную с ним логику обработки запроса доступа, которая реализована согласно стандарту.

## Решения (Decision)

**Дерево политик** должно вернуть ответ на запрос о доступе, который должен содержать одно из возможных решений:

  * *Разрешить (Allow)*

  * *Запретить (Deny)*

  * *Не применимо (Not Applicable)*

  * *Ошибка, решение не определено (Indeterminate)*

## Правило (Rule)

Согласно **XACML**, базовым блоком проверки доступа является **Правило**.

```
type Rule {
  target: Expression[],
  condition: Expression[],
  effect: Permit | Deny,
  advices: Advice[]
}
```

**Правило** может быть применимо к текущему запросу доступа или нет. Применимость **Правил** определяется по выполнению выражений-условий в полях **Назначение (target)** и **Дополнительные условия (condition)**. Если все проверки возвращают истину, значит результатом будет поле `effect`, в противном случае возвращается решение *Не применимо*, т. е. все выражения в полях **Назначение** и **Дополнительные условия** объединены через логическое `И`, однако предполагается, что в поле **Назначение** проводятся простые проверки, а в поле **Дополнительные условия** более сложные, что позволяет быстро отбрасывать неприменимые **Правила**. Под простыми выражениями в **Назначении** понимаются выражения без функций, со сравнением атрибута с константой. Это также относится к полям **Назначение** для **Политик** и **Групп политик**.

## Политика (Policy)

Политика объединяет несколько **Правил**.

```
type Policy {
  target: Expression[],
  rules: Rule[],
  combiningAlgorithm: CombiningAlgorithm,
  advices: Advice[]
}
```

Если все выражения в поле **Назначение** возвращают истину, значит **Политика** применима к текущему запросу доступа. Результатом применения **Политики** будет скомбинированный по указанному алгоритму результат на основе применения вложенных **Правил**.

Для случая, если в поле **Назначение** нет ни одного выражения, стандарт предлагает (но не требует) определять применимость **Политики** на основе **Назначения** у вложенных Правил (см. [п. 3.3.2.1](http://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-os-en.html#_Toc325047093)). Однако для большей однозначности было решено отказаться от этого в пользу следующего: если в поле **Назначение** у **Политики** нет ни одного выражения, то такая **Политика** применима к любому запросу доступа. Это же правило относится и к **Группе политик**.

## Группа политик (PolicySet)

**Группа политик** объединяет несколько **Политик** и/или **Групп политик**.

```
type PolicySet {
  target: Expression[],
  items: (Policy | PolicySet)[],
  combiningAlgorithm: CombiningAlgorithm,
  advices: Advice[]
}
```

Логика применения **Группы политик** аналогична логике применения **Политик** за исключением того, что **Алгоритм комбинирования** возвращает результат на основе вложенных **Политик** и **Групп политик**.

## Алгоритм комбинирования (Combining Algorithm)

Алгоритм комбинирования определяет алгоритм применения вложенных элементов: списка **Правил** у **Политики** и списка **(Policy | PolicySet)** у **Группы политик**.

Реализованы следующие **Алгоритмы комбинирования** из стандарта XACML:

  * Deny Overrides

  * Permit Overrides

  * Deny Unless Permit

  * Permit Unless Deny

  * First Applicable

  * Only One Applicable

Ознакомиться с описанием этих алгоритмов комбинирования можно в [Приложении С (Appendix C)](http://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-os-en.html#_Toc325047268) стандарта.

!!! Note "N.B."
    Также стоит отметить, что стандарт дополнительно определяет алгоритмы **Ordered Deny Overrides** и **Ordered Permit Overrides**. Это вариации **Deny Overrides** и **Permit Overrides**, применяющие вложенные элементы дерева согласно порядку, в котором они были указаны. Однако для простоты и однозначности все алгоритмы считаются **Ordered**.

## Решение о доступе (Decision Result)

Структура, представляющая собой ответ на запрос доступа – результат вычисления дерева политик. Содержит **Решение о доступе** и список **Рекомендаций**.

```
type DecisionResult {
  decision: Permit | Deny | NotApplicable | Indeterminate,
  advices: Advice[]
}
```

## Рекомендации (Advice)

Рекомендация может содержать набор свойств в зависимости от типа. Общий вид:

```
type Advice {
  type: string,
  appliesTo: Permit | Deny,
  attributes: { ... }
}
```

В системе **Webim** реализованы два типа **Рекомендаций**:

  * `fields` - содержит информацию об ограничении на поля сущности. Имеет смысл для разрешающих **Решений о доступе**. Например, может быть правило, разрешающее редактировать оператору свой профиль, но в этом правиле может быть дополнительно прописано ограничение на поле **Шаблоны ответов**. Как следствие, оператор не сможет редактировать свои шаблоны ответов, но сможет редактировать все остальное.

  * `redirect` - предложение перенаправить пользователя в другой раздел интерфейса. Имеет смысл для запрещающих **Решений о доступе**. К примеру, если доступ к **Панели управления** запрещен, при наличии **Рекомендации** типа `redirect` с `path='chat'`, оператора перенаправит в **РМО**.

Список **Рекомендаций** в ответе на запрос доступа формируется на основе **Решений о доступе**, возвращаемых элементами дерева согласно правилам:

  1. В **Решении о доступе** содержатся только те **Рекомендации**, которые применимы к **Решению**. Например, если решением является **Разрешить (Permit)**, то в ответе должны быть только **Рекомендации** со значением `appliesTo == 'Permit'`.

  1. Ответ от **Правила** содержит привязанные к нему **Рекомендации**.

  1. Ответ от **Политик** и **Групп политик** содержит как привязанные к ним **Рекомендации**, так и **Рекомендации** из ответов вложенных элементов, повлиявших на решение о доступе.

Ниже приведена иллюстрация, как **Рекомендации** попадают в итоговый ответ на примере **Рекомендации** с типом `reason`. Иллюстрация взята из [статьи от Axiomatics](https://axiomatics.com/blog/obligations-and-advice-in-xacml-part-2).

![Дерево политик в системе контроля доступа](https://webim.ru/kb/img/for-admins/access-control-system/base/advice-policy-tree.webp){ style="width: 499px; max-width: 100%" }

В зависимости от места применения **Решения о доступе** **Рекомендации** могут быть проигнорированы полностью или частично. Например, API сервера не учитывает **Рекомендацию** *Перенаправление*, т. к. она имеет смысл только для интерфейса.

Ответ на запрос доступа может содержать несколько **Рекомендаций** одного типа. В зависимости от типа **Рекомендации** этом случае может быть либо использована только первая попавшаяся **Рекомендация**, либо все такие **Рекомендации** будут объединены по некому алгоритму и т. п.

---

Источник: https://webim.ru/kb/for-admins/access-control-system/base.html
