Модель разрешений с пользователями и группами пользователей в DynamoDB - PullRequest
1 голос
/ 28 июня 2019

У меня есть «реляционная» модель со следующими типами:

  • Пользователи
  • Группы пользователей
  • Детали

Пользователи могут входить в несколько групп, а в группах может быть несколько пользователей.

У элементов есть пользователи и группы, которым разрешено читать или выполнять над ними операции.

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

Что я придумал до сих пор

Решением будет то, что предметы имеют следующие свойства:

  • Пользователи

    • Первичный ключ: идентификатор пользователя
    • Ключ сортировки отсутствует
    • Свойства: список групп
  • Пункты:

    • Первичный ключ: идентификатор товара
    • Ключ сортировки:
      • 'data': данные к этому пункту
      • <user/group-id>: разрешение для этого пользователя или группы

Так что для проверки прав доступа нужно будет

  • Получить группы пользователей
  • Получите разрешения, запросив идентификатор элемента с идентификатором пользователя и всеми идентификаторами группы в качестве ключей сортировки (используя BatchGetItems).
  • Убедитесь, что у пользователя или любой из его групп есть необходимые разрешения.

Вопрос

Мне кажется, что это может привести к огромным запросам, особенно когда количество групп велико.

Есть ли способ реализовать эту модель разрешений (или аналогичную модель разрешений) без столь дорогих проверок разрешений?

1 Ответ

0 голосов
/ 01 июля 2019

Краткий ответ - держите ваши разрешения отдельно от ваших данных.

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

Таблица разрешений имеет два атрибута, которые я назову entity (ключ хеша) и relationship (ключ сортировки). (Вы можете использовать любые имена, какие захотите.) Эта таблица также имеет GSI, где relationship - это ключ хеша, а entity - это ключ сортировки. Поскольку строки в этой таблице маленькие, запрос очень недорогой. Вы можете прочитать> 100 строк и использовать только 1 RCU.

Атрибут entity - это просто идентификатор пользователя или группы. Атрибут relationship является составной частью типа отношения и другого идентификатора. (Вы можете использовать все, что вы хотите для идентификаторов, но я буду использовать числа для всех моих примеров.)

Вот некоторые примеры данных:

entity      | relationship
===========================================
user-0001   | member-of:group-1000
user-0001   | member-of:group-3000
user-0002   | can-access:item-1111
user-0002   | member-of:group-2000
group-1000  | can-access:item-1111
group-2000  | can-access:item-2222

Чтобы узнать, есть ли у пользователя разрешение на доступ к данному элементу, вам нужно выполнить два запроса. Запросите таблицу разрешений для userId и запросите GSI для отношения itemId «can-access». Затем сравните результаты двух запросов, чтобы увидеть, есть ли какие-либо общие группы (или если у пользователя есть разрешение на прямой доступ к элементу).

Например, если вы хотите узнать, может ли user-0001 получить доступ к item-1111, вы запросите user-0001 и вернетесь [member-of:group-1000, member-of:group-3000]. Затем вы запросите GSI для can-access:item-1111 и вернетесь [user-0002, group-1000]. Сравнивая два результата, вы увидите, что user-0001 может получить доступ к item-1111 через group-1000.

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

entity      | relationship
===========================================
user-0001   | admin-of:group-1000
user-0001   | member-of:group-1000
user-0002   | member-of:group-2000
user-0002   | owner-of:item-1111
group-1000  | can-write:item-1111
group-1000  | can-read:item-1111
group-2000  | can-read:item-1111

В этом примере у нас также есть пользователи, которые могут администрировать группы, мы разделили права на чтение и запись для элементов и можем определить пользователя или группу как владельца элемента (что, возможно, означает, что они могут изменить, кто имеет разрешение на чтение или запись элемента).


Одно предупреждение: предполагается, что группы не могут быть вложенными. Если группы могут быть вложенными, вам потребуется больше запросов для обхода иерархии вложенных групп, и вам может быть лучше использовать AWS Neptune или другую базу данных для хранения ваших разрешений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...