Здравствуйте, Aikin. A>А можно их все же перечислить? Т.е. развернуть ответ?
Как и обещал — расписываю. Чтобы не лазить по всем постам про систему безопасности, распишу только косяки со схемой данных (о ней мы больше всего и говорили).
1) Общие косяки. Понятно, что ничего в продакшн не уйдёт и относиться надо снисходительно. Тем не менее:
1.1) Схема отвратительнейше нарисована. Дело даже не в том, что её тяжело читать. Дело в том, что из неё очень тяжко вытащить информацию которую она должна отражать. Найдите-ка связь между разрешениями и группами. Правда очевидно?
1.2) Косяки с именованием. Может товарищ и мегагуру, но большого опыта работы с базами у него явно нет. Потому что только садомазохист может называть поля с FK на табличку Groups вот так: Group, ParentGroup и OnGroup. Одновременно Есть ещё мелкие замечания по именованию остальных полей, ну да фиг с ними.
1.3) Навеки останется неизвестным, зачем товарищ убрал FK constraint между Permissions и EntitySecurityKeys. Если так надо — пусть хоть коммент на схеме оставит...
1.4) Ни одного естественного ключа. Я молчу об UQ на UsersGroups (название таблички явно тщательно выбиралось).
Summary: товарищ — асс в проектировании.
2) Пользователи и группы.
2.1) Группы вообще-то предназначены для одновременного назначения разрешений нескольким пользователям. И происходить это должно прозрачно для остальной части системы. Иначе, когда у нас появится новый тип принципалов (допустим, системные пользователи), придётся переделывать все остальные части системы. Я уже предлагал как это сделать — завести сквозной ID для пользователей и групп.
2.2) Очень любопытно посмотреть, как товарищ реализует дерево групп (а он это явно задумал, раз уж есть поле ParentGroup) с _NOT NULL_ ParentGroup.
2.3) Пользователи обычно используются для трёх вещей: представляют ID для разруливания разрешений, ассоциируют системного пользователя с некоторым реальным человеком и хранят инфу, необходимую для авторизации. С авторизацией всё по ходу мегаклассно — её просто нет. С информацией о реальном человеке ещё круче — одно поле. Зато текстовое и с запасом. Насчёт ID я уже говорил выше.
Summary: я не волшебник, я только учусь.
3) Разрешения. Вот здесь начинается помойка.
3.1) Самая грубейшая ошибка — все разрешения — в одной куче. Не, для примитивных систем это хорошо, но в реальной системе разрешения на документы и выписку накладной на шнурки надо как-то разделять
3.2) Зачем-то введены EntityGroup (он их для наследования разрешений что ли использует???)
3.3) Раз уж EntityGroup есть — как описываются разрешения на Entity Type и Specific Entity?
3.4) Что есть Type??? Учитывая специфический стиль именования — всё что угодно, начиная с типа разрешения (хотя выше уже есть allow) и заканчивая тем самым разрешением на Entity Type. Правда непонятно почему тогда поле так названо.
3.5) Совершенно крышесносящий способ назначать разрешения: на каждый тип сущностей — своё поле. При этом параллельно живут EntitySecurityKeys.
Summary: это были неправильные пчёлы.
4) Операции. Здесь мне уже страшно.
4.1) Почему Name такой же длины что и comment?
4.2) Что такое Type?
4.3) Раз уж у нас есть ParentOpertion — где FK??? Кстати, в отличие от групп, ParentOperation может содержать NULL. Гениально.
4.4) Зачем comment может содержать NULL? Пустой строки недостаточно чтобы выразить всю тоску по поводу отсутствия коммента?
4.5) Абсолютно непонятно зачем в одну кучу сваливать все возможные операции, а так же для чего они используются вообще? Для журнала? ТОгда зачем они связаны с Permission? Или это как раз элементарные действия, на которые навешиваются разрешения? А не загнёцца ли товарищ выставлять отдельно разрешения на каждое необходимое действие?
Summary: дайте мне лопату.
В сумме — если не придираться к мелочам — великолепный сборник антипаттернов. Дальнейшие статьи товарища комментировать не хочется.
P.S. Я кажется наврал — для авторизации есть accounts. Правда, почему они не связаны с пользователями —
Re: Архитектура системы безопасности "пользователь-роль-прав
Здравствуйте, Donz, Вы писали:
D>Не могли бы подкинуть статей, что почитать на эту тему?
Есть цикл сообщений в блоге Ayende на эту тему: Rhino Security
СУВ, Aikin
Re: Архитектура системы безопасности "пользователь-роль-прав
Интересно, что никто не предложил сделать анралог самой гибкой системы безопасности, которую я только знаю — Active Directory. Вкратце, идея такова — есть типы сущностей, доступ к которым надо контролировать (объекты авторизации), у каждого типа есть набор атомарных операций, которые можно произвести над типом. Ещё есть субъект авторизации (его обычно называют принципалом) — это юзер или группа. Соответственно, есть два варианта разрешений:
1. разрешение производить операцию над любым объектом данного типа.
2. разрешение производить операцию над конкретным объектом данного типа.
Логично первый тип разрешений хранить в составе принципала (пример — то, что в OS Windows называется привилегией), а второй — в качестве метаданных объекта (пример — Security Descriptor в файловой системе NTFS). Впрочем, раз уж вы просили воздержаться от обсуждения реализации, то не буду затрагивать этот момент
Здравствуйте, Sinix, Вы писали:
S>Эммм... Вы знаете, здесь два варианта. Либо мы под естественными ключами понимаем две разные вещи, либо товарищ в принципе не знает азов реляционной теории. Суррогатный ключ вводится для того, чтобы не шарить естественный ключ между сущностями.
Продолжаю не понимать претензий к отсутствию естественных ключей. Суррогатный ключ вводится для того, чтобы не мешать реляционную структуру и бизнес-логику. Естественный ключ имеет свою семантику в бизнес-логике и нужен суррогат, чтобы при изменении бизнес-правил или объективной реальности реляционная структура не страдала. Чтобы не гадать каждый раз возможно или нет подобное изменение — "азы реляционной теории" говорят нам, что проще всегда использовать суррогат и не болеть головой по этому поводу.
S>Но это вовсе не значит что естественных ключей быть не должно — вся теория нормализации и функциональные зависимости в частности работают благодаря естественным ключам.
Вся теория нормализации и функциональной зависимости работает благодаря ключам, а уж естественные они или суррогатные — зависит от проектировщика.
S> Или вы считаете что пользователь может 2 раза входить в 1 и ту же группу?
Это ты про [Id, GroupId, UserId] — ? Так [GroupId, UserId] — не естественный ключ, а составной и проблема решается констрейнтом уникальности.
Ничего фатального я тут не вижу.
Мы уже победили, просто это еще не так заметно...
Re: Архитектура системы безопасности "пользователь-роль-прав
Здравствуйте, Sinix, Вы писали:
S>Кстати это самая популярная ошибка: вводить суррогатный ключ, выкидывать UQ и утверждать что всё ок. Эквивалентное типа преобразование Претензии именно к тому, что товарищ не задал UQ на естественные ключи.
Самая ошибка (хотя не могу сказать что популярная) привязывать предметную логику к primary ключам. При развитии системы может меняться система уникальности. И как результат — большие траблы граничищие с сипукой у всей схемы. А если еще данные нужно импортить/экспортить в какие-то другие хранилища — то веревку и мыло. Поэтому правилом хорошего тона является делать суррогаты на primary key.
Дейт — конечно мужик головастый(грешен, уважаю его), однако он теоретик работающий только в парадигме реляционки(в отличие от нас). Поэтому не советую побуквенно следовать его советам.
Re[2]: Архитектура системы безопасности "пользователь-роль-п
Здравствуйте, Aikin, Вы писали:
D>>Не могли бы подкинуть статей, что почитать на эту тему? A>Есть цикл сообщений в блоге Ayende на эту тему: Rhino Security
Странно, но исходное сообщение (которое дало старт проекту Rhino Security) не "затегено": A vision of enterprise platform: Security Infrastructure
Re[5]: Архитектура системы безопасности "пользователь-роль-п
Здравствуйте, Donz, Вы писали:
D>Здравствуйте, Sinix, Вы писали:
D>[skip] D>К сожалению, с архитектурой уже все решилось — количество победило, потому второй вариант из первого поста. D>Спасибо за развернутый ответ, правда, у меня очень упрощенная схема, и половину описанного навряд ли стоит воротить, но на будущее буду знать.
Сочуствую или не сочуствую — не зная что вам надо на самом деле — не скажу. То что я описал совсем не сложная штука, она страшно смотрится только на словах.
ID — да, идентификатор объекта. Поскольку для определения разрешений должно быть пофиг кто у нас — пользователь или группа, у нас должна быть общая идентификация. Способ реалиации — GUID/промежуточная сущность/сквозная идентификация — на ваше усмотрение. Я остановился на последнем. Принципал — чисто абстракция. Выглядит как-то так:
CREATE VIEW Security.UserPrincipals AS
BEGIN
SELECT Security.CurrentUserID() AS Principal_ID, 1 AS IsUser
UNION ALL
SELECT G.ID, 0
FROM Security.Groups G INNER JOIN Security.UserGroups UG
ON G.ID = UG.Groups_ID
WHERE UG.Users_ID = Security.CurrentUserID()
END
Дальше эта вьюха используется для разруливания разрешений. Чтобы получилось читабельно, вьюха не включает в выборку родительские группы — на самом деле их надо включать, или не будет наследования разрешений. Соответственно, добавляется столбец NestingLevel.
Если чуствительна производительность — пишется триггер на логин или job, который заранее вычисляет пользовательские идентификаторы и забивает их в служебную табличку. Наш view гребёт данные из той таблицы, а не считает их динамически.
D>В конечном итоге это называется ACL, правильно?
Не-не, вы зря относитесь с таким уважением к трём волшебным буковкам. Под определение ACL подходит и то что я написал, и ваш вариант, и подход informix'а (хотя я не пойму зачем вычислять на каждый чих _все_ разрешения — наверно так надо).
В моём варианте ACL — это табличка OrderPermissions с атрибутами {Principal_ID, Order_ID, AllowedActionsBitmask, DeniedActionsBitmask...}, причём будет один ACL на каждую область — для заказов, документиков и т.п. Вы ведь не хотите в одном списке держать разрешения на важные документы и на заполнение заявок на туалетную бумагу
ACL реально нужно только в сложных сценариях. Как правило я просто завожу хранимые процедуры, что выполняют примитивные действия и даю execute права на них ролям СУБД. Дальше добавляем пользователя в роль — вуаля, есть разрешения
Другими словами: ACL нужны для разруливания прав на уровне конкретных сущностей. Для ограничения доступа к системе пользуйтесь стандартными средствами — например безопасностью СУБД.
Re: Архитектура системы безопасности "пользователь-роль-прав
Может конеш религия — тем не менее: дерево групп/ролей + многие-ко-многим между пользователями и группами.
С одной стороны достаточно гибко, с другой — не даёт создать эдакую "паучью сеть" когда непонятно кто от кого и как получает разрешения. Плюс явно виден порядок распространения разрешений.
Дальше. Не стоит заводить "право" вообще — замучаетесь. Выделите вместо этого отдельные области в которых будете рулить разрешениями (чаще всего это будут отдельные подсистемы/модули). В этих областях определите атомарные действия — типа "создать сущность a, изменить сущность b" и т.п.
Сопоставьте каждому атомарному действию битовый флаг. Дальше определите пресеты — наборы битовых операций, которые определяют допустимые операции для каждого разрешения. Если пресет небольшой — представьте в виде инта. И собсно напоследок — назначение разрешений: пара id пользователя/группы — пресет.
В результате разрешения считаются при помощи элементарных битовых операций.
Интересует что конкретное/предложения/возражения — вэлкам
Re[10]: Архитектура системы безопасности "пользователь-роль-
Здравствуйте, Sinix, Вы писали:
S>Тааак. Давайте придерживаться одной терминологии что ли.
Нивапрос.
S>Дейта я вам щас не поцитатю, но память (и википедия) выдаёт следующее: S>Естественный ключ — ключ-кандидат, что состоит исключительно из user data attributes (columns если больше нравится).
Ну вот, user data attributes — это что? Правильно — данные имеющие семантику в предметной области. И чтобы не нагружать их еще семантикой в контексте реляционных структур и вводят суррогаты.
S>ЕК вполне может быть и составным — в чём проблема?
Может, но в данном случае составной ключ состоит из 2х суррогатов.
S>Кстати это самая популярная ошибка: вводить суррогатный ключ, выкидывать UQ и утверждать что всё ок.
Что такое UQ?
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re: Архитектура системы безопасности "пользователь-роль-прав
Здравствуйте, Donz, Вы писали:
D>Не могли бы подкинуть статей, что почитать на эту тему?
D>Как должна быть организована зависимость между этим сущностями "пользователь", "роль", "право" в общем случае? D>Какой из подходов более верный (опять же в общем случае): D>1)Пользователь содержит данные о том, какие роли ему назначены. Роли содержат данные о том, какие права они собой представляют. D>2)Пользователь содержит данные о том, какие роли ему назначены. Права содержат данные о том, в какие роли они включены.
D>Своя точка зрения присутствует, но пока писать ее не буду. Хотелось бы услышать аргументированные "за" и "против" или вообще третий вариант зависимостей между этими сущностями.
Вобщем-то разницы никакой — все равно нужно получить набор прав пользователя в итоге. Роли\группы в данном раскладе как бы только для удобства. Но второй вариант все таки странен — напиши код получения прав пользователя и посмотри как оно получается. Но повторюсь — по большому счету разницы нет — ибо само отношение между сущностями инвариант в обоих схемах.
WBR, Igor Evgrafov
Re: Архитектура системы безопасности "пользователь-роль-прав
Мы ввели абстракцию, которой принадлежат права — SID.
В Hibernate соответственно User.getSid().getPermissions() и Role.getSid().getPermissions(), в базе — таблица SID с OWNER_ID без FK.
Re[6]: Архитектура системы безопасности "пользователь-роль-п
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Aikin. A>>А можно их все же перечислить? Т.е. развернуть ответ?
S>Как и обещал — расписываю. Чтобы не лазить по всем постам про систему безопасности, распишу только косяки со схемой данных (о ней мы больше всего и говорили).
S>1) Общие косяки. Понятно, что ничего в продакшн не уйдёт и относиться надо снисходительно. Тем не менее: S>1.1) Схема отвратительнейше нарисована. Дело даже не в том, что её тяжело читать. Дело в том, что из неё очень тяжко вытащить информацию которую она должна отражать. Найдите-ка связь между разрешениями и группами. Правда очевидно?
Прямая связь, без доптаблиц. В чем проблема?
S>1.2) Косяки с именованием. Может товарищ и мегагуру, но большого опыта работы с базами у него явно нет. Потому что только садомазохист может называть поля с FK на табличку Groups вот так: Group, ParentGroup и OnGroup. Одновременно Есть ещё мелкие замечания по именованию остальных полей, ну да фиг с ними.
Просто стиль именования отличный от твоего, впрочем как и от моего.
S>1.3) Навеки останется неизвестным, зачем товарищ убрал FK constraint между Permissions и EntitySecurityKeys. Если так надо — пусть хоть коммент на схеме оставит...
Блог явно накидывался по только что созданой схеме, отсюда мелкие косяки (видно, что Accounts и EntitySecurityKeys не сохранены). Это vision, а не законченное решение.
S>1.4) Ни одного естественного ключа. Я молчу об UQ на UsersGroups (название таблички явно тщательно выбиралось).
Возможно он просто убежденный противник естественных ключей, это не преступление.
S>2) Пользователи и группы. S>2.1) Группы вообще-то предназначены для одновременного назначения разрешений нескольким пользователям. И происходить это должно прозрачно для остальной части системы. Иначе, когда у нас появится новый тип принципалов (допустим, системные пользователи), придётся переделывать все остальные части системы. Я уже предлагал как это сделать — завести сквозной ID для пользователей и групп.
Их можно унаследовать от одной сущности и сделать действительно сквозной ID, но это тоже не фатальный недостаток. Я ничего не понял про проблему системных пользователей, достаточно сделать новую группу просто.
S>2.2) Очень любопытно посмотреть, как товарищ реализует дерево групп (а он это явно задумал, раз уж есть поле ParentGroup) с _NOT NULL_ ParentGroup.
Да, это явно невнимательность, для vision простительно.
S>2.3) Пользователи обычно используются для трёх вещей: представляют ID для разруливания разрешений, ассоциируют системного пользователя с некоторым реальным человеком и хранят инфу, необходимую для авторизации. С авторизацией всё по ходу мегаклассно — её просто нет. С информацией о реальном человеке ещё круче — одно поле. Зато текстовое и с запасом. Насчёт ID я уже говорил выше.
1. Ты путаешь авторизацию и аутентификацию, это серия постов именно по авторизации, аутентификация тут никаким боком.
2. Привязка пользователя к реальному человеку это часть бизнес логики, нет никакого смысла приплетать ее в этом посте.
S>3) Разрешения. Вот здесь начинается помойка. S>3.1) Самая грубейшая ошибка — все разрешения — в одной куче. Не, для примитивных систем это хорошо, но в реальной системе разрешения на документы и выписку накладной на шнурки надо как-то разделять
Что мешает их разделять?
S>3.2) Зачем-то введены EntityGroup (он их для наследования разрешений что ли использует???)
In addition to all of that, we also have the concept of an EntityGroup to consider. Permissions can be granted and revoked on an Entity Group, and those are applicable to all the entities that are member in this group. This way, business logic that touches permissions doesn't need to be scattered all over the place, when a state change affects the permissions on an entity, it is added or removed to an entity group, which has a well known operations defined on it.
S>3.3) Раз уж EntityGroup есть — как описываются разрешения на Entity Type и Specific Entity?
S>3.4) Что есть Type??? Учитывая специфический стиль именования — всё что угодно, начиная с типа разрешения (хотя выше уже есть allow) и заканчивая тем самым разрешением на Entity Type. Правда непонятно почему тогда поле так названо.
Тип разрешения очевидно.
S>3.5) Совершенно крышесносящий способ назначать разрешения: на каждый тип сущностей — своё поле. При этом параллельно живут EntitySecurityKeys.
Не увидел вообще ни одного поля завязанного на конкретный тип бизнес сущности.
S>4) Операции. Здесь мне уже страшно. S>4.1) Почему Name такой же длины что и comment?
Такие вещи тебя серьезно пугают?
S>4.2) Что такое Type?
Тип операции? Возможно это объясняется где-то позже, без этого знания вполне можно понять мысль автора.
S>4.3) Раз уж у нас есть ParentOpertion — где FK??? Кстати, в отличие от групп, ParentOperation может содержать NULL. Гениально.
Забыто FK, это тебя тоже очень пугает?
S>4.4) Зачем comment может содержать NULL? Пустой строки недостаточно чтобы выразить всю тоску по поводу отсутствия коммента?
А вот оракл вообще не различает NULL и пустую строку, может его заклеймить позором за это? Мелкая придирка.
S>4.5) Абсолютно непонятно зачем в одну кучу сваливать все возможные операции, а так же для чего они используются вообще? Для журнала? ТОгда зачем они связаны с Permission? Или это как раз элементарные действия, на которые навешиваются разрешения?
Как зачем? Разрешения определяют разрешена ли (запрещена ли) операция или доступ к сущности.
S>А не загнёцца ли товарищ выставлять отдельно разрешения на каждое необходимое действие?
Товарищ явно умеет автоматизировать свою деятельность, не загнется.
S>В сумме — если не придираться к мелочам — великолепный сборник антипаттернов. Дальнейшие статьи товарища комментировать не хочется.
Именно к мелочам я и увидел придирки. В основном к схеме базы, она тут второстепенная вещь, это vision архитектурного решения, как персистить его данные дело десятое.
S>P.S. Я кажется наврал — для авторизации есть accounts. Правда, почему они не связаны с пользователями —
Нет, аккаунты там как пример бизнес сущности. Вобщем ты просто пробежал статью по диагонали и половины не понял. Возмножно в этом виновата сама статья. Следовало обратить внимание на название (конкретно на слово vision) и "Just to note: this is not complete"
Здравствуйте, Sinix, Вы писали:
S>А попробуйте погуглить компонент TDeveloper, и интероп врапперы к dev/head, dev/hands.
А точно не кривые нагуглить можно? Мне бы ещё время нагуглить да побольше
S>Если не стебаться, то система безопасности — это настолько интимная тема, что пускать туда абы кого ну совершенно не следует. Последствия в принципе по аналогии можно вывести
Ну, например, есть промышленные решения для защиты от тиражирования.
У форумных движком и CMS системы безопасности вполне даже открытые -- можно выдрать и скопировать.
Можно же сделать готовое решение для "внутреннего" ПО хотя бы, никто никогда его взламывать не будет и исходники анализировать, а разделение пользователей, прав доступа и ролей требуется. Задача то хорошо ведь формализуется.
Здравствуйте, Sinix, Вы писали:
S>Так что примерно представляю когда удобней будет rbac, а когда acl (или вы претендуете на изобретение более оригинальных концепций? ).
Однако несложно построить систему, которая будет поддерживать и ту, и другую концепции одновременно Что, собственно, мы и сделали в компании.
Не могли бы подкинуть статей, что почитать на эту тему?
Как должна быть организована зависимость между этим сущностями "пользователь", "роль", "право" в общем случае?
Какой из подходов более верный (опять же в общем случае):
1)Пользователь содержит данные о том, какие роли ему назначены. Роли содержат данные о том, какие права они собой представляют.
2)Пользователь содержит данные о том, какие роли ему назначены. Права содержат данные о том, в какие роли они включены.
Своя точка зрения присутствует, но пока писать ее не буду. Хотелось бы услышать аргументированные "за" и "против" или вообще третий вариант зависимостей между этими сущностями.
22.12.10 01:12: Перенесено модератором из 'Архитектура программного обеспечения' — kochetkov.vladimir
Спасибо за подробное объяснение, но тут скорее интересует архитектура, чем конкретное техническое решение. Битовые маски будут использоваться в любом случае. От "прав" уже не деться, да и не вижу причин от них отказываться. Если что, я под "правом" понимаю некое атомарное действие, на которое у пользователя либо есть право выполнения, либо нет. Можно сказать, это объект с двумя возможными типами доступа: "можно все", "нельзя ничего".
[skip] S>Сопоставьте каждому атомарному действию битовый флаг. Дальше определите пресеты — наборы битовых операций, которые определяют допустимые операции для каждого разрешения. Если пресет небольшой — представьте в виде инта. И собсно напоследок — назначение разрешений: пара id пользователя/группы — пресет.
Имеется в виду, что пользователь может быть включен в несколько групп плюс у него могут быть отдельные установки на конкретные права (то бишь, пресет)?
Можно сказать, это основной вопрос. На данный момент в проекте преполагается, что назначение отдельных прав конкретному пользователю невозможно, и все права раздаются только через роли. У меня есть большие сомнения, что не появится исключений, при которых одними ролями не обойтись, а создавать новую роль, которую будут видеть все (пользователей очень много), ради одного пользователя нелогично.
Если назначение конкретного права пользователю все-таки понадобится, то при первом подходе из начального поста нужно будет дополнить структуру только пользователя. Сами "права" как не знали о том, кто их может использовать, так и далее не будут знать, то есть достигается некоторый уровень абстракции.
При втором подходе придется изменять структуру как пользователей, так и прав. Насколько я понял, аргумент в пользу этого метода заключается в том, что объект "право" будет содержать данные о всех субъектах (ролях), которые к нему имеют доступ. Правда, при прямом назначении права пользователю непонятно, как это красиво сделать. И конкретно мне непонятно, зачем нужно хранить данные о субъектах в объекте, когда объектов мало, и они навряд ли будут меняться, а субъектов очень много, при этом они постоянно изменяются в случае с пользователем и могут редко меняться в случае с ролями.
Re[3]: Архитектура системы безопасности "пользователь-роль-п
у вас право в себе объединяет две независимые сущности — действие и тип разрешения. Сейчас у вас только 2 состояния — можно все", "нельзя ничего". Что будет, если вам потребуется состояние "может делегироваться другому"? Можно конеш добавить ещё битиков. А "наследовать на n уровней вниз"? Так что нефиг смешивать Гораздо лучше завести отдельно действия и отдельно списки разрешаемых действий, списки наследуемых действий и т.п. Всё равно наследование этих разрешений должно производиться отдельно, а вычисление результирующего разрешения — в самом конце. Понадобится новый тип обработки равзрешений — заведёте новый список и добавите в него те же самые действия, только и всего.
// мы всё ещё говорим об архитектуре — список действий вполне может превратиться в битовую строку
Теперь про группы. У вас опять идёт смешивание 2 механизмов — назначения разрешений и управления пользователями. В результате вы огребётесь при малейшем изменении требований. Разделите задачи:
1) Для администратора у вас есть пользователи и группы.
2) Для разруливания разрешений — список принципалов текущего пользователя (принципал — общий термин для объектов, которым даются разрешения) и список назначенных разрешений, что содержит кортеж
{id принципала,id объекта,пресет разрешённых действий,пресет запрещённых действий...}.
3) Ограничение типов принципалов должно решаться при назначении разрешений(в идеале дублируется constraint'ом в базе).
Могу предложить корявоизящный вариант: id пользователей -нечётные, групп — чётные. Дальше делаете ограничения — в список разрешений A могут добавляться только принципалы с чётными идентификаторами. В список B — все кто угодно и т.п. // упс, опять меня в реализацию понесло
Напоследок: никакие изменения в вычислении/назначении разрешений не должны влиять на способ описания пользователей/групп. Это разные системы.
Если недоответил/что-то упустил — пинайте, исправлюсь
Re[4]: Архитектура системы безопасности "пользователь-роль-п
[skip]
К сожалению, с архитектурой уже все решилось — количество победило, потому второй вариант из первого поста.
Спасибо за развернутый ответ, правда, у меня очень упрощенная схема, и половину описанного навряд ли стоит воротить, но на будущее буду знать.
S>Теперь про группы. У вас опять идёт смешивание 2 механизмов — назначения разрешений и управления пользователями. В результате вы огребётесь при малейшем изменении требований. Разделите задачи: S>1) Для администратора у вас есть пользователи и группы. S>2) Для разруливания разрешений — список принципалов текущего пользователя (принципал — общий термин для объектов, которым даются разрешения) и список назначенных разрешений, что содержит кортеж S>{id принципала,id объекта,пресет разрешённых действий,пресет запрещённых действий...}.
Я так понимаю, тут под id объекта понимается идентификатор субъекта (пользователь, роль и т.д.)? Если принципал — это и есть объект, то зачем еще один объект?
В конечном итоге это называется ACL, правильно?
Re[2]: Архитектура системы безопасности "пользователь-роль-п
В принципе нечто подобное и описывал, правда не настолько абстрактно
1) проще реализовать силами СУБД — оно есть из коропки
2) — списки ACL + хранимки которые используют списки для фильтрации
Конеш можно написать всё и целиком с нуля, но это дичайший гемморой, особенно в плане сквозной авторизации/интеграции с внешними системами.
Re[3]: Архитектура системы безопасности "пользователь-роль-п
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, koandrew.
S>В принципе нечто подобное и описывал, правда не настолько абстрактно S>1) проще реализовать силами СУБД — оно есть из коропки S>2) — списки ACL + хранимки которые используют списки для фильтрации
S>Конеш можно написать всё и целиком с нуля, но это дичайший гемморой, особенно в плане сквозной авторизации/интеграции с внешними системами.
На самом деле ничего сложного тут нет, и если правильно абстрагироваться от хранилища, то можно построить очень гибкую систему. Как вы понимаете, прозрачно прикрутить AD сюда вообще элементарно, а, исходя из моего опыта, именно интеграция с AD является самым большим геморроем в случае самопальных подсистем авторизации. В данном же случае при соответствующей реализации можно вообще управлять доступом к объектам вашей системы через стандартные административные снап-ины вроде ADUC, за что админы будут на вас молиться — ибо им не придётся осваивать ваш интерфейс, а пользоваться уже известным им. Плюс политики, скрипты (и всё это "искаропки") — в общем, не думаю, что нужно описывать преимущества данного подхода. Те, кому доводилось админить с помощью скриптов сетки с Exchange, Sharepoint, отлично понимают, о чём это я
А хранимки или не хранимки — это тема отдельной "беседы", не имеющей к архитектуре никакого отношения Вон в форуме .NET не утихают баталии на эту тему. Но всё же не удержусь и выскажу своё мнение — хранимки — это зло
1) про самописный контроль доступа: это реальнейшая попа в крайних ситуациях — например, когда требуется делегировать текущий контекст внешним системам. Тут уж проще использовать стандартные фичи из коробки. В остальном — согласен и поддерживаю.
2) про хранимые процедуры: а для чего вы их хотите использовать?
ХП удобны для инкапсуляции реальных структур данных и для реализации подхода "sql живёт только на сервере". View для этого использовать на порядок сложнее — допустим, в SQL Server'e без специальных приседаний OUTPUT clause не возвращает значения от insetad of триггера. Ну а давать клиенту прямой доступ к табличкам не всегда возможна. Что остаётся?
Ну и уже кучу раз сталкивался, что интеграция на уровне СУБД — полная фигня по сравнению с попыткой использования API чужих софтин. Чемпион — госовский модуль сбора данных, что требовал координаты комбобокса на его форме чтобы получить оттуда выбранное значение
Re[5]: Архитектура системы безопасности "пользователь-роль-п
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, koandrew!
S>1) про самописный контроль доступа: это реальнейшая попа в крайних ситуациях — например, когда требуется делегировать текущий контекст внешним системам. Тут уж проще использовать стандартные фичи из коробки. В остальном — согласен и поддерживаю.
Согласен, иногда это может вылиться в приличный гемор. Однако на практике мне приходилось решать только обратные задачи Ну и для делегации контекста можно (если можно) заюзать имперсонацию — это как бы тоже "из коробки" Вообще очень многие вещи упрощаются, если юзать AD-авторизацию
S>2) про хранимые процедуры: а для чего вы их хотите использовать? S>ХП удобны для инкапсуляции реальных структур данных и для реализации подхода "sql живёт только на сервере". View для этого использовать на порядок сложнее — допустим, в SQL Server'e без специальных приседаний OUTPUT clause не возвращает значения от insetad of триггера. Ну а давать клиенту прямой доступ к табличкам не всегда возможна. Что остаётся?
Давайте не будем об этом тут? Если "хотите об этом поговорить" — создавайте отдельную тему — там поспорим. А тут оффтопить не стоит... Вкратце моя позиция по этому вопросу — интеграция на уровне БД — зло, я стараюсь использовать БД только как внутреннюю подсистему конкретного API, закрывая доступ в неё иначе как через него. Так проще масштабировать компоненты системы(stateless API vs stateful DB), да и интероп через веб-сервисы как средство интеграции мне импонирует гораздо больше (помимо всего прочего, они кроссплатформенны). Просто я обычно проектирую системы по принципу "чёрных ящиков" и минимизирую зависимости. При таком подходе чаще всего можно без проблем обойтись plain SQL, и, соответственно, не завязываться на конкретный сервер...
Мммм поаккуратней со статьёй — там в схеме данных практически все ошибки о которых я предупреждал. Внимательно читайте схему — она крайне криво отрисована...
Re[4]: Архитектура системы безопасности "пользователь-роль-п
Здравствуйте, Sinix, Вы писали:
A>>>Есть цикл сообщений в блоге Ayende на эту тему: Rhino Security A>>Странно, но исходное сообщение (которое дало старт проекту Rhino Security) не "затегено": A vision of enterprise platform: Security Infrastructure
S>Мммм поаккуратней со статьёй — там в схеме данных практически все ошибки о которых я предупреждал. Внимательно читайте схему — она крайне криво отрисована...
А можно их все же перечислить? Т.е. развернуть ответ?
Re[5]: Архитектура системы безопасности "пользователь-роль-п
В понедельник полно отвечу.
Сейчас:
1) сущности человек и пользователь объединены в 1
2) грабли с общим ID у пользователя/группы -его нет
3) уже не помню
4) все разрешения — в 1-й куче.
Re[7]: Архитектура системы безопасности "пользователь-роль-п
О! Контркритика пошла
Чтобы не размазывать по цитатам: я рассматривал эту статью именно как пример как делать. С этой точки зрения там скорее пример как _не_ делать. Каждый мелкий косяк по отдельности не страшен конечно, но в целом оно производит впечатления сырого наброска. Ну и во многом говорит о том, насколько автор ответственно подходит к решению проблемы. Если эта статья чисто для понтов, типа "посмотрите как я могу", её вообще бессмысленно давать как пример (и облсуждать тоже). Если же это претензия на код, который в будущем уйдёт в продакшн, то автора надо срочно изолировать от написания security-sensitive кода.
Теперь по цитатам. То, что можно пообсуждать дальше, выделил жирным.
S>>1.1) Схема отвратительнейше нарисована. Дело даже не в том, что её тяжело читать. Дело в том, что из неё очень тяжко вытащить информацию которую она должна отражать. Найдите-ка связь между разрешениями и группами. Правда очевидно? Z>Прямая связь, без доптаблиц. В чем проблема?
Дык читайте: "Схема отвратительнейше нарисована.". Я здесь говорю только о картинке-схеме. Диаграмме, если больше так нравится. Для вас сразу видно что разрешения и группы связаны? И можете даже из схемы сказать по каким столбцам?
Z>Просто стиль именования отличный от твоего, впрочем как и от моего.
Ну нелогично ведь одно и то же по смыслу поле три раза называть по-разному. Это не стиль именования а его отсутствие. Не, отдельные товарищи и tbl000123.fldstr12 как стиль понимают...
Z>Блог явно накидывался по только что созданой схеме, отсюда мелкие косяки (видно, что Accounts и EntitySecurityKeys не сохранены). Это vision, а не законченное решение.
Дык где большие красные буковки дисклаймера? Я привык что люди думают перед тем как постить картинки. А то кто-нить начитается и пойдёт реализовывать свои "системы безопасности"
Z>Возможно он просто убежденный противник естественных ключей, это не преступление.
Эммм... Вы знаете, здесь два варианта. Либо мы под естественными ключами понимаем две разные вещи, либо товарищ в принципе не знает азов реляционной теории. Суррогатный ключ вводится для того, чтобы не шарить естественный ключ между сущностями. Но это вовсе не значит что естественных ключей быть не должно — вся теория нормализации и функциональные зависимости в частности работают благодаря естественным ключам. Или вы считаете что пользователь может 2 раза входить в 1 и ту же группу?
Z>Их можно унаследовать от одной сущности и сделать действительно сквозной ID, но это тоже не фатальный недостаток. Я ничего не понял про проблему системных пользователей, достаточно сделать новую группу просто.
Понятие принципала ведь не идиоты придумывали. Системе вычисления разрешений должно быть глубоко пофиг на пользователей и группы. Ей должны быть известны только id, соответствующие текущему контексту выполнения (id, разумеется может быть несколько). Как эти id сопоставляются контексту — глубоко не её дело. Чтобы объяснить почему так должно быть надо заводить отдельный топик. Если интересует — отпишусь.
Системные пользователи — это отдельный тип принципалов. Обычно заводятся для всяких внутренних процедур обслуживания по расписанию типа бэкапа и т.п.
Z>Да, это явно невнимательность, для vision простительно.
Дык тут эту статью уже советуют как образец. А для товарища, которому доверили разработать систему безопасности enterprise-уровня такое как раз непростительно. Об уровне однозначно свидетельствует.
Z>1. Ты путаешь авторизацию и аутентификацию, это серия постов именно по авторизации, аутентификация тут никаким боком. Ага. Описка. Стыдно.
Z>2. Привязка пользователя к реальному человеку это часть бизнес логики, нет никакого смысла приплетать ее в этом посте. Э неее, это часть системы безопасности, ибо никакая безопасность без индивидуальной ответственности смысла не имеет. Уж поверьте как человеку, немало на этом огрёбшему
S>>3) Разрешения. Вот здесь начинается помойка. S>>3.1) Самая грубейшая ошибка — все разрешения — в одной куче. Не, для примитивных систем это хорошо, но в реальной системе разрешения на документы и выписку накладной на шнурки надо как-то разделять
Z>Что мешает их разделять?
Ну у товарища просто заведена общая сущность разрешения. Естесвенного ключа здесь быть не может. "Разрешениями вообще" рулить особого смысла не имеет. У вас же не будет одного администратора по шнуркам и документам? Так что абстрактные разрешения особого смысла не имеют.
S>>3.2) Зачем-то введены EntityGroup (он их для наследования разрешений что ли использует???)
Z>
Z>In addition to all of that, we also have the concept of an EntityGroup to consider. Permissions can be granted and revoked on an Entity Group, and those are applicable to all the entities that are member in this group. This way, business logic that touches permissions doesn't need to be scattered all over the place, when a state change affects the permissions on an entity, it is added or removed to an entity group, which has a well known operations defined on it.
Ну дыкть говорю ж — для наследования разрешений по сущностям. Крайне опасная штука из-за своей неочевидности, лучше уж наследовать по естественным связям.
S>>3.4) Что есть Type??? Учитывая специфический стиль именования — всё что угодно, начиная с типа разрешения (хотя выше уже есть allow) и заканчивая тем самым разрешением на Entity Type. Правда непонятно почему тогда поле так названо. Z>Тип разрешения очевидно.
А Allow тогда зачем??? Уличная магия в общем.
S>>3.5) Совершенно крышесносящий способ назначать разрешения: на каждый тип сущностей — своё поле. При этом параллельно живут EntitySecurityKeys.
Z>Не увидел вообще ни одного поля завязанного на конкретный тип бизнес сущности.
Не, вы меня не поняли: на группы — свой fk, на пользователей — свой... это именно следствие кривого дизайна принципалов.
S>>4.1) Почему Name такой же длины что и comment? Z>Такие вещи тебя серьезно пугают?
Ага. Это явное отсутсвие здравого разума: сделано абы было. Чисто логически коммент — подробное описание, имя — краткое имя. Если описание по длине может совпадать с именем — в чём его смысл? Для бизнесподелок ещё пойдёт, для системы безопасности -слишком халтурно.
S>>4.2) Что такое Type? Z>Тип операции? Возможно это объясняется где-то позже, без этого знания вполне можно понять мысль автора.
См. самую первую претензию. Диаграммы рисуются чтобы их читали, а не чтобы показать что автор мегаумный чувак.
S>>4.3) Раз уж у нас есть ParentOpertion — где FK??? Кстати, в отличие от групп, ParentOperation может содержать NULL. Гениально. Z>Забыто FK, это тебя тоже очень пугает?
Не, меня пугает быдлоподход в разработке.
S>>4.4) Зачем comment может содержать NULL? Пустой строки недостаточно чтобы выразить всю тоску по поводу отсутствия коммента? Z>А вот оракл вообще не различает NULL и пустую строку, может его заклеймить позором за это? Мелкая придирка.
Неа, ещё один нюанс, свидетельствующий о низкой квалификации. Имя не допускает null. Другие текстовые поля — тоже. Явное отсутсвие единого стандарта. Так что нефиг
S>>А не загнёцца ли товарищ выставлять отдельно разрешения на каждое необходимое действие? Z>Товарищ явно умеет автоматизировать свою деятельность, не загнется.
Администрирование на уровне атомарных операций — моветон. Равно как и использование операций для описания несвязанных действий. Надо заводить что-то типа пресетов операций и назначать уже их. Почему — тоже надо расписывать в отдельном посте.
Z>Именно к мелочам я и увидел придирки. В основном к схеме базы, она тут второстепенная вещь, это vision архитектурного решения, как персистить его данные дело десятое.
ы Не, ребят. Для быдлобизнеса такая безответственность может и пойдёт. Для Security критична любая мелочь. У товарища security не только персистится, оно ещё и считается на сервере. Так что как отмазка не катит.
S>>P.S. Я кажется наврал — для авторизации есть accounts. Правда, почему они не связаны с пользователями —
Z>Нет, аккаунты там как пример бизнес сущности.
О. Т.е. товарищ вводит общего предка (EntitySecurityKey) только ради назначения разрешений????
И как же тогда у него работает связь пользователь-контекст выполнения???
Re[9]: Архитектура системы безопасности "пользователь-роль-п
Здравствуйте, IB, Вы писали:
Тааак. Давайте придерживаться одной терминологии что ли. Дейта я вам щас не поцитатю, но память (и википедия) выдаёт следующее:
Естественный ключ — ключ-кандидат, что состоит исключительно из user data attributes (columns если больше нравится).
ЕК вполне может быть и составным — в чём проблема?
ЕК — самое обычное ограничение и выполняют ту же роль что и остальные ограничения: описывает предметную область.
Кстати это самая популярная ошибка: вводить суррогатный ключ, выкидывать UQ и утверждать что всё ок. Эквивалентное типа преобразование Претензии именно к тому, что товарищ не задал UQ на естественные ключи.
Re[11]: Архитектура системы безопасности "пользователь-роль-
Тэкс,ребят, а ничего что мы о разных вещах в принципе говорим, а? Мне очень интересно как из
Суррогатный ключ вводится для того, чтобы не шарить естественный ключ между сущностями. Но это вовсе не значит что естественных ключей быть не должно — вся теория нормализации и функциональные зависимости в частности работают благодаря естественным ключам
можно сделать вывод, что естественные ключи должны быть primary??? Для мну это настолько бредовая идея, что я как-то даже забыл это чётко выделить. Виноват%)
Давайте уж напишу сейчас.
PK должен быть суррогатным. То что у нас есть PK, вовсе не значит что мы можем не включать информацию об остальных ключах в БД. Именно к отсутсвию UQ (ака unique constraint) и были все претензии.
Так лучше?
Re[11]: Архитектура системы безопасности "пользователь-роль-
А есть ли готовые уже библиотеки, которые позволяют минимальными усилиями добавить такой или подобный функционал в уже готовое приложение? двухзвенное? энзвенное?
Здравствуйте, _k_, Вы писали:
_k_>А есть ли готовые уже библиотеки, которые позволяют минимальными усилиями добавить такой или подобный функционал в уже готовое приложение? двухзвенное? энзвенное?
А попробуйте погуглить компонент TDeveloper, и интероп врапперы к dev/head, dev/hands.
Если не стебаться, то система безопасности — это настолько интимная тема, что пускать туда абы кого ну совершенно не следует. Последствия в принципе по аналогии можно вывести
_k_>Можно же сделать готовое решение для "внутреннего" ПО хотя бы, никто никогда его взламывать не будет и исходники анализировать, а разделение пользователей, прав доступа и ролей требуется. Задача то хорошо ведь формализуется.
Улыбнуло. Огрёбся немало с "хорошо ведь формализуется". Причём и как кодер, и как админ, и как саппорт. Спасибо, не надо
Свою точку зрения где-то в начале топика расписывал.
Здравствуйте, _k_, Вы писали:
_k_>Ваша позиция понятна... То есть "коробчатых" решений не видели?
Ну как вам сказать-то
Вот AD — коробчатое решение? Или безопасность в SQL Server'e? Или шарпойнт? Или (не к ночи будь помянут) 1С?
А я могу ещё кучу страшных буковок повспоминать
Так что примерно представляю когда удобней будет rbac, а когда acl (или вы претендуете на изобретение более оригинальных концепций? ).
В общем контроль доступа слишком связан с БЛ, чтобы его можно было реализовать как отдельную самостоятельную систему.
Отдельные детали конструктора есть. Остальное — ваши проблемы
Здравствуйте, _k_, Вы писали:
_k_>А есть ли готовые уже библиотеки, которые позволяют минимальными усилиями добавить такой или подобный функционал в уже готовое приложение? двухзвенное? энзвенное?
Net Framework. Особенно если в качестве сервера присутсвует ASP.NET.
Здравствуйте, _k_, Вы писали:
_k_>А есть ли готовые уже библиотеки, которые позволяют минимальными усилиями добавить такой или подобный функционал в уже готовое приложение? двухзвенное? энзвенное?
Мы используем Spring Security. Но, естественно, конкретная релизация лежит на нас. Из либы, если не ошибаюсь, берем только самые общие вещи: Principal, интерфейс аутентификации, контекст безопасности.
Здравствуйте, koandrew, Вы писали:
K>Однако несложно построить систему, которая будет поддерживать и ту, и другую концепции одновременно Что, собственно, мы и сделали в компании.
Ага. У нас аналогично: RBAC используется для раздачи доступа к приложениям/базовых ролей в приложениях, ACL для тонкого тюнинга разрешений. Таки весьма удобно. Правда там не совсем ACL...
Здравствуйте, Sinix, Вы писали:
S>Как и обещал — расписываю. Чтобы не лазить по всем постам про систему безопасности, распишу только косяки со схемой данных (о ней мы больше всего и говорили).
Просто вопрос: а ты читал (хотя бы просматривал) остальные сообщения автора?
You can read the post about it to get a feeling about what I had in mind when I thought it up.
When it came the time to actually implement them, however, it turn out that as usual, the implementation is significantly different than the design in all the details. Here is the overall detail of the entities involved.
СУВ, Aikin
Re[7]: Архитектура системы безопасности "пользователь-роль-п