масштабируемая модель данных безопасности - PullRequest
2 голосов
/ 16 марта 2012

В прошлом я использовал следующую простую модель данных для обеспечения безопасности в моих приложениях.Я хотел бы иметь неявное запрещение, явное разрешение и явное запрещение , которое последующий мог бы перевесить перед предыдущим.

enter image description here

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что мое текущее приложение должно быть масштабируемым до десятков миллионов записей.В приведенной выше модели данных для каждой записи у меня может быть много записей ACL.Поэтому, если в моей таблице записей (acltest_uspaceData) есть 10 миллионов строк, в моих таблицах безопасности acl может быть гораздо больше.

Является ли это подходящей моделью данных для количества записей, которые мы планируем хранить? Если нет, Что я могу сделать с этой моделью данных, чтобы сделать ее масштабируемой?

Я использую PostGIS в качестве базы данных.

Обновление - Правила:

  1. Следует подразумевать, что никто не имеет доступа ни к чему, если для этой записи не созданы сопоставления безопасности.
  2. Чтобы разрешить доступ пользователям или группам, вы должны явно разрешить им доступ к этой записи через некоторыеассоциация безопасности.
  3. Чтобы запретить кому-либо доступ, который уже имеет доступ через членство в группе, вы должны явно запретить этому человеку доступ к этой записи через ассоциацию безопасности.

Ответы [ 2 ]

1 голос
/ 20 марта 2012

Исходя из ваших правил безопасности, acltest_role_acl.allowed выглядит избыточным - если имеется запись ACL роли, то можно подразумевать allowed == true.Если, конечно, вам не нужна возможность «отзывать» целые группы, а не только отдельных пользователей.

Кроме того, ваша модель выглядит хорошо, и вам следует сосредоточиться на ее эффективном хранении в базе данных.

В случае, если ваша СУБД поддерживает это, вероятно, будет хорошей идеей хранить ACL в виде кластеризованной таблицы :

  • Если вы хотите эффективно ответить на вопрос "которыйЗаписи ACL имеют данную запись ", тогда порядок столбцов PK в кластеризованной таблице должен быть {record_id, user_id} для ACL пользователя и {record_id, role_id} для ACL роли.
  • Если вы хотите эффективно ответить на вопрос"какие записи ACL имеет данный пользователь или роль ", то порядок столбцов PK должен быть обратным (т. е. {user_id, record_id} и {role_id, record_id}).
  • Если вы хотите эффективно ответить Оба вопросы, вам понадобится указатель в обоих «направлениях».К сожалению, вторичные индексы являются дорогостоящими в кластеризованных таблицах, поэтому в этом случае вы можете рассмотреть возможность использования таблицы на основе кучи и двух обычных индексов.

Если ваша СУБД поддерживает это, вы можете сжать передний крайиндекс кластеризации (в Oracle он называется таблицей СЖАТЫЙ ИНДЕКС, ОРГАНИЗОВАННЫЙ).Это устранит некоторую избыточность, возникающую из повторяющихся списков ACL (из ваших комментариев: «обычно много людей с одинаковыми разрешениями» и «существует много строк с одинаковыми разрешениями»).


С другой стороны, если вы в первую очередь беспокоитесь о стоимости хранилища (и / или используете СУБД, которая не поддерживает сжатие), но не возражаете против повышенной сложности и потенциального влияния на производительность, вы могли бы рассмотреть что-тонапример:

enter image description here

Поскольку многие записи имеют одинаковые списки ACL (согласно вашему комментарию), эта модель позволит избежать большей части повторений.

Например,если N записей имеют одинаковые 5 записей ACL:

  • Для старой модели потребуется N * 5 записей ACL строк .
  • Для новой модели потребуется только 6 строк+ N поля , что намного дешевле с точки зрения хранения (6 строк = 5 записей ACL + 1 группа, и поле: acltest_uspaceData.acl_group_id).

Проблема заключается в: когда вы вставляете новую запись, как выind "соответствующая" группа ACL?Это можно решить примерно так, но это будет не очень эффективно:

SELECT *
FROM acltest_aclGroup
WHERE
    NOT EXISTS (
        SELECT user_id, allowed
        FROM acltest_users_acl
        MINUS -- Or EXCEPT, depending on the DBMS.
        SELECT user_id, allowed
        FROM <user_acl_tmp>
    )
    AND NOT EXISTS (
        SELECT user_id, allowed
        FROM <user_acl_tmp>
        MINUS
        SELECT user_id, allowed
        FROM acltest_users_acl
    )
    AND NOT EXISTS (
        SELECT role_id
        FROM acltest_role_acl
        MINUS
        SELECT role_id
        FROM <role_acl_tmp>
    )
    AND NOT EXISTS (
        SELECT role_id
        FROM <role_acl_tmp>
        MINUS
        SELECT role_id
        FROM acltest_role_acl
    )

Сначала вы создаете временную таблицу для ACL пользователей и ролей (<user_acl_tmp> и <role_acl_tmp>), затем вставляете ACLзаписи, которые новая запись должна иметь в них, затем выполните вышеупомянутый запрос, который ищет существующие группы ACL для установления равенства с временными ACL.

0 голосов
/ 16 марта 2012

Я не авторитет в этом вопросе, но кто-то из моих знакомых, который разрабатывает услуги облачной платформы для одного из крупнейших провайдеров CDN в стране, решительно поддерживает OpenLDAP в случаях, когда важна масштабируемость. Я не уверен, будет ли он соответствовать вашим требованиям ACL, но небольшое исследование должно сказать.

...