Контроль доступа
В данной статье рассматриваются несколько вариантов организации доступа к функционалу web - систем с хранением информации о доступе в таблицах базы данных.
- Что такое "Контроль доступа"
- Контроль доступа основанный на числовых уровнях доступа
- Контроль доступа основанный на пользователях
- Контроль доступа основанный на группах пользователей
- Контроль доступа основанный на области ответственности
Контроль доступа - что это?
В одно-пользовательском, настольном приложении, нет необходимости в системе контроля доступа - пользователь имеет доступ к каждой функции в приложении (иначе на кой там эти функции). Однако в многопользовательском приложение, которое развернуто на нескольких сетевых ресурсах, более чем вероятно, что потребуется организация доступа. Это, как правило, требует наличие следующей информации:
- Список всех функций, доступных в системе. Эти "функции" иногда называют "операции" или "задачи".
- Список всех лиц (пользователей), которым разрешен доступ к приложению в целом. Обычно эта информация используется в процессе входа в систему, через которую каждый пользователь должен пройти, прежде чем получить доступ к любой части приложения.
- Список разрешений, который определяет, кому - какие функции доступны.
Как правило, каждый пункт перечисленный выше требует наличия своей таблицы в базе данных. Существует несколько способов, разграничить права доступа для разных пользователей, но каждый способ имеет свои преимущества и недостатки. Вот некоторые из них:
Контроль доступа основанный на числовых уровнях доступа
- Проста как апельсин: для неё требуется всего две таблицы в базе данных - таблица, содержащая данные о пользователях "USERS" и таблица, содержащая данные о задачах "TASKS" - без каких-либо отношений между ними, как показано на рисунке:
Рисунок 1 - Контроль основанный на уровнях доступа

При такой организации доступа каждая задача получает номер уровня безопасности - число в диапазоне от 1 до N, где 1- самый низкий, а N - самый высокий уровни. Каждому пользователю тоже присваивается определённый уровень доступа, как следствие ему разрешен доступ только к тем задачам, которые имеют уровень безопасности ниже или равный уровню пользователя. Таким образом, пользователь с уровнем безопасности "5" может получить доступ к задачам, которые имеют уровень безопасности в диапазоне 1-5.
Засада с этой системой в том, что она полностью кумулятивна - вы можете повысить уровень доступа пользователя, тем самым разрешив ему выполнять задачи с более высоким уровнем, но вместе с тем - вы не можете отнять у него право выполнять задачи, которые имеют более низкий уровень доступа. В добавок доступ к задачам, которые имеют один и тот же уровень доступа фактически осуществляется как к неделимым группам. Например, есть два пользователя , 'A' и 'B', и две задачи, 'A' и 'B'. Теперь попытаемся дать пользователю 'A' доступ к задаче 'A', но не к задаче 'B', и доступ пользователю "B" к задаче "B", но не к задаче "А". Хрен нам - в данной системе это не возможно. Подытожим:
- Если обе задачи имеют одинаковый уровень безопасности, то доступ может быть предоставлен либо к обеим, либо ни к одной из них.
- Если задача "А" имеет более низкий уровень безопасности, чем задача "Б", то при добавлении доступа пользователю к задаче "Б" - доступ к задаче "А"открывается автоматом - сие плохо!
Контроль доступа основанный на пользователях
Здесь чуть сложнее -доступ определяется для каждого пользователя. Фактически здесь мы имеем отношение многие-ко-многим выраженное таблицей "PERMISSIONS" между пользователями "USERS" и задачами "TASKS". Здесь разрешения "PERMISSIONS" предстают в виде связующей таблицы. Пример на рисунке.
Рисунок 2 - пользователь разрешений на основе системы

Есть несколько вариантов реализации данной системы:
- В системах со сложными задачами - там, где одна задача может работать в режимах: "СОЗДАТЬ", "ПРОЧИТАТЬ", "ОБНОВИТЬ", "УДАЛИТЬ"- доступ к задаче будет включать в себя все эти режимы.
- Если доступ к отдельным режимам в рамках задачи требует отдельного разрешения, то запись в таблице "PERMISSIONS" должна иметь флаги "0/1" для каждого из этих режимов. Сие часто называют CRUD матрицами (где "CRUD" обозначает аббревиатуру: Create, Read, Update, Delete) расположения строк и столбцов напоминает разрешения матрицы.
- В системе с простыми задачами, где не требуется "порежимный" доступ - CRUD матрицы не требуются.
Недостатком этой конструкции является то, что, управление доступом производится для каждого пользователя персонально - в системах, с большим количеством пользователей это может занимать большой объем времени.
Контроль доступа основанный на группах пользователей
В этой системе доступа пользователи разделились на группы и разрешения назначаются группам, а не отдельно взятым пользователям, смотрим рисунок ниже.
Рисунок 3 - группа разрешений на основе системы

Такая система доступа имеет следующие преимущества:
- Как только пользователь был идентифицирован - система узнает его GID (GroupIDentifier - идентификатор группы), это все, что требуется для доступа к таблицы разрешений.
- Любые изменения, внесенные в разрешения группы будут автоматически наследоваться всеми членами этой группы
- Изменения в разрешениях группы может быть сделано очень легко, поскольку требуется изменить данные только в одной таблице - таблицы разрешений.
- Пользователя можно очень просто переключать между разными группами - просто сменив ему его GID.
В этой системе доступа таблицы пользовательских групп "USER-GROUP" иногда называют "SECURITY-CLASS" или "ROLE".
Контроль доступа основанный на области ответственности
В этой системе доступа пользователь может принадлежать более чем одной группе одновременно. Такая система доступа включает в себя две таблицы-отношения "USER-USER-GROUP" и "TASK-USER-GROUP" как показано на рисунке 4.
Рисунок 4 - ответственность разрешений на основе системы (простой)

таблицу "USER-GROUPS" иногда называют областью ответственности, поскольку каждый пользователь может иметь ответственность в более чем в одной области, т.е. принадлежать более чем одной группе.
Такая система доступа имеет следующие недостатки:
- Добавить разрешения можно только, связав пользователя с ещё одной группой. Нет возможности отмены существующих разрешений даже путем добавления новой группы в которой эти разрешения не прописаны. Т.е. работа с разрешениями осуществляется только на уровне групп.
- Требуется обслуживать две таблицы-отношения: "USER-USER-GROUP" и "TASK-USER-GROUP".
Конечно, если накуриться мухоморов посеръезнее то можно придумать и более продвинутый вариант системы доступа, основанной на областях ответственности показан на рисунке 5.
Рисунок 5 - (комплексная) система доступа основанная на ответственности

В этой системе доступа есть уже пять таблиц-отношений многие-ко-многим, которые предоставляют более мощный уровень настройки доступа. Можно так же задействовать CRUD-матрицы при создании записей - разрешений . Но здесь вам придётся обрабатывать логические конфликты. Что это значит? Это значит, следующее: так как разрешения предоставляются из пяти! таблиц, разрешение, предоставленное записью из одной таблицы может быть отменено записью из другой таблицы. В итоге процесс просчёта разрешений становиться довольно большим геморроем.
В итоге хоть, в теории такая система доступа и представляется гораздо более гибкой, на практике это создает определённый проблемы в реализии и юзабельности, т.к. сложно отслеживать отменённые/перекрытые права доступа. Так что выбирать Вам. Ну, а у кого какие ещё идеи на сей счет - прошу делиться в комментариях.
Данная статья является моим вольным переводом этой статьи Тони Марстона: A Role-Based Access Control (RBAC) system for PHP