Каковы лучшие практики по авторизации списка ресурсов? - PullRequest
5 голосов
/ 04 октября 2008

Публикация и / или совместные приложения часто предполагают совместное использование доступа к ресурсам. На портале пользователю может быть предоставлен доступ к определенному контенту в качестве члена группы или из-за явного доступа. Полный набор контента может включать в себя общедоступный контент, контент членства в группах и контент частного пользователя. Или, с приложениями для совместной работы, мы можем захотеть передать ресурсы как часть рабочего процесса или разделить хранение документа для целей редактирования.

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

У меня два вопроса:

  1. Достаточно легко авторизовать пользователя после того, как вы получили ресурс, но как эффективно выполнить авторизацию в списке доступных ресурсов? И,

  2. Можно ли этот вид авторизации отделить от ядра приложения? Возможно, в отдельный сервис? После разделения, как вы можете отфильтровать запросы типа «Получите мне все документы, которые я вижу с заголовком, например [SomeSearchTerm]»? Мне кажется, что ваша отдельная система должна была бы скопировать много справочных данных.

Ответы [ 3 ]

5 голосов
/ 23 ноября 2008

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

Штеффен также создал свой собственный плагин под названием «Декларативная авторизация», который, кажется, соответствует вашим потребностям, ИМХО:

  • с одной стороны, вы определяете ролей (например, "посетитель", "администратор" ...). Ваши пользователи связаны с этими ролями (в отношениях «многие ко многим»). Вы сопоставляете эти роли с привилегиями (опять же в отношении многих ко многим). Каждая привилегия связана с данным контекстом . Например, роль " посетитель " может иметь привилегию " читать документы ". В этом примере « read » является привилегией и применяется к контексту « documents ».
    • Примечание: в плагине Steffen вы можете определить иерархию ролей. Например, вам может потребоваться, чтобы роль « global_admin » включала роль « document_admin », а также роль « comment_admin » и т. Д.
    • Вы также можете определить иерархии привилегий: например, привилегия " manage " может включать в себя " read ", " update ", " добавить"и" удалить"привилегии.
  • с другой стороны, вы кодируете свое приложение в терминах привилегий и контекстов , а не в терминах ролей. Например, действие по отображению документа должно проверять только то, имеет ли пользователь право « read » в контексте « documents » (нет необходимости проверять, есть ли у пользователя Роль " посетитель " или любая другая роль). Это значительно упрощает ваш код, поскольку большая часть логики авторизации извлекается в другом месте (и, возможно, даже определяется кем-то другим).

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

class DocumentController [...]
  filter_access_to :display, :require => :read
  def display
    ...
  end
end

А внутри вида:

<html> [...]
  <% permitted_to?(:create, :documents) do %>
  <%= link_to 'New', new_document_path %>
  <% end %>
</html>

Плагин Steffen также позволяет управлять доступом на уровне объекта (т.е. на уровне строки). Например, вам может потребоваться определить роль, например " document_author ", и дать ей привилегию " manage " для " Documents ", но только если пользователь является автором документа. Объявление этого правила, вероятно, будет выглядеть так:

role :document_author do
  has_permission.on :documents do
    to :manage
    if_attribute :author => is {user}
  end
end

Вот и все! Теперь вы можете получить все документы, которые пользователь может обновлять следующим образом:

Document.with_permissions_to(:update)

Поскольку привилегия " manage " включает в себя привилегию " update ", будет возвращен список документов, автором которых является текущий пользователь.

Конечно, не каждому приложению нужен такой уровень гибкости ... но ваше может.

0 голосов
/ 05 октября 2008

Хотя ваш вопрос достаточно проработан, на самом деле отсутствует какой-то контекст.
Что определяет документы, для которых у пользователя есть привилегии? Может ли пользователь редактировать только свои «собственные» файлы? Здесь есть ролевый механизм? Является ли он более ориентированным на MAC (то есть пользователь может видеть уровень безопасности)? Есть ли определяющий атрибут для данных (например, отдел)?

Все эти вопросы вместе могут дать лучшую картину и дать более конкретный ответ.

Если документы «принадлежат» конкретному пользователю, это довольно просто - есть поле «владелец» для документа. Затем запросите все документы, принадлежащие пользователю.
Аналогичным образом, если вы можете предварительно определить список именованных пользователей (или ролей), которые имеют доступ, вы можете запросить объединенный список между документами, списком авторизованных пользователей / ролей и пользователем (или его ролями).
Если пользователь получает разрешения в соответствии со своим отделом (или другим аналогичным атрибутом документа), вы можете запросить его.
Точно так же вы можете запрашивать все документы с уровнем безопасности, равным или ниже уровня привилегий пользователя. Если это динамический рабочий процесс, каждый документ, как правило, должен быть отмечен своим текущим состоянием и / или следующим ожидаемым шагом; какие пользователи могут выполнить этот следующий шаг - это просто другая привилегия / роль (обрабатывать то же, что и выше).
Тогда, конечно, вы захотите сделать СОЮЗ ВСЕХ между всеми этими и публичными документами ...

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

0 голосов
/ 04 октября 2008

У меня обычно такая схема

Пользователи & минус; & минус; & isin; Пользовательские документы & ni; & minus; & minus; Документы

Затем я создаю представление «ProfiledDocuments»

SELECT <fields> 
FROM Documents d 
INNER JOIN UserDocuments ud on ud.DocumentId = d.Id 
INNER JOIN Users u ON u.Id = ud.UserId

Затем выполните поисковые запросы в ProfiledDocuments, всегда используя фильтр UserId. С соответствующими индексами это работает достаточно хорошо.

Если вам нужны более сложные разрешения, вы можете сделать это с помощью дополнительного поля в таблице «многие ко многим» в UserDocuments, в котором указывается тип разрешения.

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