- PVSM.RU - https://www.pvsm.ru -
В моей дебютной статье [1] мы по шагам проектировали модель разграничения доступа к предметной области, рассматривая в качестве примера выдуманную ECM систему, которая от простой постепенно становилась не очень простой. Мы столкнулись с проблемами, которые не смогли легко и просто решить в рамках той модели, что у нас получилась в результате. В этой статье попытаемся исправить положение.
MAC (Mandatory Access Control) — в том случае, если доступ к объектам настраивает администратор декларативно, но не конечный пользователь системы.
DAC (Discretionary Access Control) – в том случае, если доступ к объектам настраивает сам пользователь (к тем объектам, «владельцем» которых он является)
Multilevel – если доступ настраивается по отношению к некоему «уровню доступа», а объекты уже помечаются каким-то признаком, определяющим нужный уровень доступа для работы с этим объектом.
Access Matrix – если доступ настраивается непосредственно между объектом и субъектом безопасности. Частным случаем этой модели является предмет наших страданий, т.е. модель доступа на основании Access Control List (списка доступа). А есть ещё один частный случай – модель доступа на основании Capabilities. Отличаются они тем, что ACL — это список тех, кто имеет права по отношению к какому-то одному объекту, а Capabilities (или C-List) – это список объектов с правами доступа к ним по отношению к какому-то субъекту безопасности. сравнение 1 (англ) [2], сравнение 2 (англ) [3]
Role-Based Access Control (RBAC) – если доступ настраивается по отношению к ролям пользователя, объединяющих возможность выполнения различных функций системы с правами по отношению к объектам безопасности. На эту модель есть стандарт [4]
Attribute-Based Access Control (ABAC) – если доступ настраивается по отношению… нет, не к атрибутам объектов. А по отношению к объектам, обладающим каким-то признаком. Типичный пример разграничения доступа на основании ABAC: менеджер Петров автоматически получает доступ к любым договорам, но только если у них Сумма меньше 100к.
На фоне всего этого ещё болтается такой термин, как Access Control Session, который периодически подмазывают то к RBAC, то к ABAC и который в вольной трактовке означает то, что субъект безопасности может обладать нескольким набором привилегий, но для совершения какой-то определённой операции ему разрешается использовать только один набор, для чего эта операция выполняется в рамках сессии безопасности, с которой оный набор и ассоциирован.
Теперь давайте посмотрим какие же модели безопасности используются для нашей простой ECM системы, занимающейся (напоминаю) обеспечением документооборота организации (ну вы уже поняли, что их там будет не одна).
Итак:
В общем, сборная солянка.
От всего этого у меня только две мысли:
Чтобы грамотно решить наши вышеозначенные проблемы – вернёмся чуть назад, к самой первой картинке
Текущая схема содержит список доступа для каждого объекта предметной области.
Из теоретической части мы уже примерно поняли, какие паттерны разграничения доступа должна поддерживать наша модель безопасности.
Поэтому будем повышать градус абстракции. Будем в ACL указывать не список субъектов безопасности с их правами, а список моделей доступа, применимых к данному объекту. При этом главенство модели ACL над всеми остальными будем поддерживать соблюдением аксиомы – мы должны всегда иметь возможность доступ к объекту вычислить исключительно на основании его ACL.
Итак, изменяем схему следующим образом
Тут и далее – схема классов, а не схема БД. Вопросами маппинга схемы классов на БД озаботимся позднее (в следующей статье). Белая закрытая стрелочка – это наследование. Открытая стрелочка – это ассоциация
Как вы уже поняли – список доступа к документам выродился в некий иерархический список поддерживаемых объектом SecurityAspect – абстрактных механизмов предоставления доступа. SecurityAspect реализованы нами с помощью паттерна Composite [5].
Прошу заметить, что я для паттерна Composite не указал промежуточную сущность для связи много ко многим между SecurityAspectComposite и SecurityAspect. В остальных случаях (не касающихся паттерна Composite) я буду такие промежуточные сущности указывать.
Также обращаю внимание на то, что SecurityAspect не ссылаются на Object. Наоборот, Object содержит ссылку на корневой SecurityAspect, который и будет (вместе со своей иерархией) определять доступ к данному объекту.
В дальнейшем корневой SecurityAspect объекта (вместе со своей иерархией) я буду по-старинке обзывать ACL.
Из теоретической части (и из наших требований, изложенных в проблеме 2) мы поняли, что пользователь системы может обладать несколькими наборами привилегий, причём в один момент времени активной должен быть только один набор.
Простой пример – если пользователь системы может работать от своего имени, от имени начальника и от имени совсем большого начальника (типичный сценарий работы секретаря) – бизнес логике системы быстро настанет кирдык, если в каждый конкретный момент не будет понятно от имени кого пользователь совершает то или иное действие в системе.
Отразим всё это на схеме.
Как мы видим, каждый пользователь может иметь набор ассоциированных с ним Principal, которые могут образовывать иерархии (также с помощью паттерна Composite [5]). Для наглядности мы завели конкретные реализации – Principal для орг. структуры организаций.
Кроме того, на диаграмме присутствует и Session, которая, кроме ссылки на пользователя, также ссылается и на тот Principal, от имени которого работает пользователь в данный момент.
Доступ в дальнейшем мы будем предоставлять не пользователям, а Principal’ам. Это позволит легко реализовать сценарии замещения (проблема 2).
Теперь давайте скрестим эти две схемы и реализуем непосредственный доступ к объектам через Principal’s.
Мы создали потомка нашего SecurityAspect с именем DirectAccess, который имеет как список прав по отношению к объекту, так и ссылку на Principal, для которого эти права собственно и доступны.
Обратите внимание, что, в отличии от модели данных в предыдущей статье [1], в этой модели права не являются атрибутами, а выделены в отдельную сущность Right, которая связана с DirectAccess через DirectAccessRights. Это позволит нам в будущем безболезненно этот набор прав расширять.
Как я обещал ранее, в нашей системе тоже будут роли. Реализуем
Как мы видим – создан новый SecurityAspect с именем Role, который может объединять в себе иерархически другие SecurityAspect’s (т.к. отнаследован от SecurityAspectComposite).
Поскольку роли чаще всего используются для декларативного назначения прав и не будут указываться в ACL объектов (хотя наша модель это и не запрещает) – нам надо обеспечить связь между ролями и Principal’ами. Делаем это с помощью PrincipalSecurityAspects.
Более подробно про использование ролей:
Cамое важное:
Давайте реализуем Multilevel модель безопасности, т.е. раздачу прав на основании какого-нибудь признака объекта. Пусть это будет ObjectKind.
Как видим – объекты стали иметь классифицирующий признак ObjectKind и появился новый наследник от SecurityAspectLeaf (что как бы намекает, что он не может содержать иерархию других SecurityAspect) с именем ObjectKindAccess. Связь между ним и Principal’ом обеспечивается также как и в случае с Role через PrincipalSecurityAspect.
Самое важное:
И напоследок у нас осталась проблема 1 с зависимыми списками доступа.
Напомню суть – объекты, обладая каждый своим списком доступа, участвуя в одном бизнес-процессе, часто должны быть доступны всем участникам этого процесса. Т.е. если какой-то пользователь имеет доступ к объекту А, то он также должен иметь доступ и к объекту Б (обычно с ограниченным набором прав).
Реализуем
Как у нас водится – мы создали нового наследника от SecurityAspectComposite с именем LinkedAccess.
Хитрость в том, что этот SecurityAspect будет «оборачивать» корневой SecurityAspect связанного объекта, таким образом предоставляя доступ всем тем, кто имел доступ к нему, и к текущему объекту. Права же, определённые на LinkedAccess через LinkedAccessRights будут либо ограничивать в правах имеющих доступ к связанному объекту, либо расширять их набор прав (в зависимости от требований бизнес-логики).
В следующей статье будем заниматься маппингом всего этого на БД учитывая обязательное требование из первой статьи [1]
“архитектурные решения, стоящие за решением вышеозначенных проблем абсолютно точно не должны влиять на скорость фильтрации объектов при поисках и должны минимально влиять на скорость совершений операций над объектами и над списками объектов (в том числе, большими).»
Design Patterns for Role-Based Access Control [6]
Patterns and Pattern Diagrams for Access Control [7]
Patterns for Session-Based Access Control [8]
Автор: Dronopotamus
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/razrabotka/113487
Ссылки в тексте:
[1] дебютной статье: https://habrahabr.ru/post/277111
[2] сравнение 1 (англ): http://slideplayer.com/slide/5738389/
[3] сравнение 2 (англ): http://www.eros-os.org/essays/ACLSvCaps.html
[4] стандарт : http://csrc.nist.gov/groups/SNS/rbac/
[5] Composite: https://en.wikipedia.org/wiki/Composite_pattern
[6] Design Patterns for Role-Based Access Control: http://ceur-ws.org/Vol-180/paper05.pdf
[7] Patterns and Pattern Diagrams for Access Control: http://secpat.de/fileadmin/user_upload/Publikationen/Trustbus_114.pdf
[8] Patterns for Session-Based Access Control: https://core.ac.uk/download/files/370/11536459.pdf
[9] Источник: https://habrahabr.ru/post/278031/
Нажмите здесь для печати.