В статье на одной странице рассмотрены основные принципы разграничения доступа на основе ролей и разрешений (RBAC).
1. Роли и разрешения
Для разграничения прав доступа пользователей вводятся 2 основных понятия — роли и разрешения. В коде они являются сущностями одной природы, так как наследуются от одного и того же класса. Однако для разграничения доступа желательно использовать их по смыслу, вложенному в названиях «роль» и «разрешение».
Роль принято назначать пользователю, тогда как разрешения не назначаются пользователям напрямую, а всегда через какую-то роль. В этом смысле роль по уровню иерархии можно поставить на 1-е место.
Можно сказать, что роль — это логически связанная древовидная совокупность разрешений, которые являются расширениями роли как класса. Различные по смыслу совокупности разрешений логично выделять в отдельные роли. При этом роли, как правило, сами связывают друг с другом в иерархическое дерево наследования.
Наличие разрешения у пользователя — это ответ на вопрос «Все ли разрешения в цепочке наследования от рассматриваемого разрешения до роли пользователя возвращают true?». Таким образом, результат ответа на этот вопрос совпадает с результатом логической операции «И» между всеми слагаемыми. Если хоть одно слагаемое вернёт false, весь результат будет равен false.
Последним в цепочке наследования всегда проверяется наличие роли у самого пользователя, но это тривиальный случай, который можно не принимать во внимание, поскольку он всегда даст true. Проверка роли, это, фактически, тоже проверка разрешения, оформленного в виде роли как таковой.
2. Правила (rules)
До сих пор мы говорили о разрешениях по факту их наличия или отсутствия: есть разрешение, выводим true, нет разрешения — на нет и суда нет (false). Но зачастую этого недостаточно, так как для получения результата не обойтись без некоторых вычислений.
Другими словами, разрешения могут содержать внутреннюю логику, а могут её не содержать. Обычно, если в существующее разрешение требуется встроить какую-то логику, оно делится на безусловное (то, что было до этого) и условное разрешение, причём безусловное наследуется от условного.
Логику оформляют в виде правила, которому дают имя. Это имя связывается с определённым разрешением. Тогда при проверке разрешения будет задействована соответствующая логика.
3. Множественные маршруты
Иногда от одного разрешения до конечной роли можно пойти несколькими путями, по разным цепочкам наследования. Как определить, по какой из этих цепочек будет получен правильный результат?
Стандартный алгоритм таков:
- Сначала выполняется проход по одной цепочке. Допустим, на каком-то звене мы получаем false.
- Тогда происходит переключение на другой маршрут.
Если мы получаем true при проходе по первому маршруту, то альтернативный маршрут вообще не задействуется, хотя он может быть короче.