Создайте лучшую систему контроля доступа - PullRequest
19 голосов
/ 14 августа 2010

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

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

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

Accounts

  • Счета представляют одного или нескольких пользователей
  • Каждый пользователь может иметь определенные разрешения или роли для учетной записи (например, владелец учетной записи или «может добавить нового пользователя»)
  • Все аккаунты привязаны к типу аккаунта

Типы счетов

  • Типы учетных записей имеют ноль или много ролей типов учетных записей
  • Типы учетных записей имеют ноль или много типов учетных записей

Тип учетной записи Роли

  • Например, "Владелец", "Администратор", "Опытный пользователь", "Гость" и т. Д.
  • Роли типа учетной записи представляют собой набор разрешений типа учетной записи

Тип учетной записи Разрешения

  • Разрешения типа учетной записи - это конкретные действия в системе, которые логика приложения будет проверять по
  • Они могут ссылаться на родителя, поэтому они могут быть иерархически сгруппированы
  • т.д .:
    • «Управление пользователями»
      • «Добавить пользователя»
      • «Удалить пользователя»
  • Эти разрешения могут быть специально для функции типа учетной записи

Особенности типа учетной записи

  • Функции типа учетной записи могут быть активированы для учетной записи, чтобы дать ей больше разрешений
  • Например, "Стандартный аккаунт" или "Премиум аккаунт"
  • Эти функции, если они активированы для учетной записи, предоставляют владельцу учетной записи больший доступ к системе
  • Они отслеживаются при активации или деактивации и могут выставляться счета периодически или по требованию

Вопросы

Каков наилучший способ проверки логики приложения на предмет действий пользователя? Я думал о сохранении всех разрешений пользователя в объекте для их сеанса (что потребовало бы выхода из системы / входа в систему для обновления разрешений, что я не фанат - какие-либо идеи по управлению разрешениями в реальном времени?):

{
  "All Permissions": {
    "User Management": {
        "Add User",
        "Delete User"
    },
    "Premium Account": {
        "Download Files",
        "Upload Files"
    },
  }
}

Затем я бы объявил разрешения, необходимые для определенного действия в системе. Может быть что-то вроде:

Permission::require('Add User');

Если заявленные разрешения отсутствуют в объекте разрешений пользователей, запрос не будет выполнен. Это кажется довольно интенсивным для каждого действия пользователя. Кроме того, что если в другом подмножестве разрешений есть строка «Добавить пользователя»?

Заранее спасибо за любую помощь в этом!

Ответы [ 9 ]

12 голосов
/ 14 августа 2010

Глядя на ваши разрешения типа учетной записи, кажется, что вы имеете в виду дизайн системы в стиле списка контроля доступа (ACL).

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

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

Кроме того, это было сделано ранее (хотя на удивление мало возможностей для реализации, на которые мы можем взглянуть); возможно взгляните на Rhino Security . Оригинальная ссылка http://ayende.com/Blog/category/548.aspx не работает, поэтому ссылка на интернет-архив сохраняется для справки.

4 голосов
/ 14 августа 2010

Один из способов, который мне понравился, это своего рода «каскадные» разрешения. У вас есть базовый набор разрешений - скажем, для чтения, записи, удаления - и они могут быть назначены группе или пользователю.

READ    USER1
READ    USER2
WRITE   USER2
READ    USER3
WRITE   USER3
DELETE  USER3

В качестве альтернативы вы можете указать «группу» вместо имени пользователя.

READ    SUBSCRIBER
READ    EDITOR
READ    ADMIN
WRITE   EDITOR
WRITE   ADMIN
DELETE  ADMIN
USER1   SUBSCRIBER
USER2   EDITOR
USER3   ADMIN

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

3 голосов
/ 18 августа 2010

Вот два моих смысла, чего бы это ни стоило.

Сначала я бы сказал, когда вы начинаете проектировать это, подумайте об ООП и о том, как оно будет применяться к сущностям в системе.Пользователи, User_Role, Roles, Role_Permissions, Accounts, Account_Types, Account_Type_Features и т. Д.

USERS: - Должно быть разрешено использовать OpenID, когда он набирает обороты - Возможность выбора между идентификаторомили UUID для переносимости базы данных

РОЛЬ ПОЛЬЗОВАТЕЛЯ: (не РОЛИ УЧЕТНОЙ ЗАПИСИ) Я бы посоветовал вам быть очень конкретным здесь.Например, где вы проводите грань между опытным пользователем и администратором?В чем разница между ADMIN и ВЛАДЕЛЕЦОМ?Пока они четко определены (и не размыты), это будет работать.Если есть какие-либо вопросы среди вашей пользовательской базы, довольно скоро у вас будет сложный набор ролей и разрешений.Я бы свел это к минимуму, чтобы все было чисто.Пользователи поймут, как работать с тем, что им дают.Кроме того, я бы изменил это на РОЛИ ТИПА ПОЛЬЗОВАТЕЛЯ.Роли должны применяться к пользователю, а не к учетной записи.

РАЗРЕШЕНИЯ НА РОЛЬ: (не РАЗРЕШЕНИЯ НА ТИП АККАУНТА) Это должно быть изменено на РАЗРЕШЕНИЯ НА РОЛЬ.Разрешения распространяются на роль пользователя, а не на учетную запись или пользователя.По моему опыту, чем яснее дизайн, тем меньше места для путаницы в будущем.Кроме того, избегайте ACL, как чума.Сделайте это простыми отношениями один к одному.Мне еще предстоит найти причину для реализации ACL для любой веб-системы.Другие системы, основанные на разрешениях, намного легче понять, поддерживать и использовать.Нет смысла усложнять этот вопрос.

ОСОБЕННОСТИ ТИПА УЧЕТНОЙ ЗАПИСИ: Будьте осторожны, чтобы не затенить Разрешения типа учетной записи и Функции типа учетной записи.Ваша первая точка маркера использует слово permissions.Измените это на особенности.Тип учетной записи активирует более расширенные / расширенные функции (не разрешения).

Управление разрешениями: Для приложения без сохранения состояния, запущенного в Интернете, сеансы - это путь.Преимущество заключается в том, что нет обходных путей к БД, чтобы постоянно проверять, авторизован ли пользователь.

Permission::require() должен следовать тем же определениям параметров, что и сеансы.Это предотвратит перекрытие других подмножеств разрешений.Таким образом, вызов будет выглядеть примерно так: Permission::require('User Management', 'Add User'); Это означает, что он будет искать $_SESSION['All Permissions']['User Management']['Add User'] Это предотвратит неоднозначность.

Помните, что SIMPLE ЛУЧШЕ.

3 голосов
/ 14 августа 2010

Я бы взглянул на систему Java на предмет разрешений:

http://download.oracle.com/javase/6/docs/api/java/security/Permission.html

Используется «логика импликации»;то есть, объект разрешения - это то, что решает, разрешено ли данное действие (то есть, подразумевает ли разрешение доступ к ресурсу).Я также проверил бы BasicPermission, поскольку он имеет довольно простую спецификацию пространства имен для разрешений.В вашем примере это будет (по номенклатуре CRUD)

  • user.create
  • user.delete
  • file.read
  • file.create

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

логическое значение isAuthorized = user.permissions.implies (requiredResource.permission);(подразумевается стандартная инкапсуляция)

, чтобы определить, разрешен ли пользователю доступ.

2 голосов
/ 20 августа 2010

Советую заглянуть в Zend_Acl от Zend Framework. Как и большинство пакетов Zend, у него крутая кривая обучения. Но когда вы полностью овладеете отношениями ресурса, действия, роли, это станет очень универсальной и мощной основой для ваших собственных реализаций ACL.

Проведите некоторое исследование существующих пакетов и шаблонов ACL.

2 голосов
/ 15 августа 2010

У Зеда Шоу было несколько интересных вещей о ACL и их ограничениях. Обязательно стоит посмотреть, прежде чем идти дальше по этому маршруту.

http://vimeo.com/2723800

1 голос
/ 18 августа 2010

Семантика, которую вы используете, немного сбивает с толку.Например, типы учетных записей «Владелец», «Администратор», «Опытный пользователь», «Гость» больше похожи на «Типы пользователей».

Кроме того, возможно, вы могли бы сделать вещи, которые вы называете "AccountPermissions", подклассом Account.Таким образом, в зависимости от типа учетной записи будут применяться разные разрешения.

1 голос
/ 14 августа 2010

У меня нет конкретных советов, но две системы, с которыми я знаком, имеют очень хорошие гибкие системы доступа / разрешения: Drupal и Plone. Вы можете сделать гораздо хуже, чем копировать, как работает любой из них. За ними стояли годы реальных испытаний.

0 голосов
/ 27 мая 2011

Взгляните сюда http://www.sqlrecipes.com/database_design/fine_grained_role_based_access_control_rbac_system-3/

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

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