Как лучше обрабатывать разрешения (а не роли) в членстве asp.net, в частности, в ASP.NET MVC

Существует множество вопросов (и информации) о настройке членства asp.net, поставщиков ролей и т.п. Независимо от того, следует ли использовать встроенную платформу, предоставляемую Microsoft, или роль, расширяйте базовые классы и свою роль.

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

Традиционно вы создавали бы роли, например, "Менеджер", "Администратор", "Сотрудник", "Суперпользователь" ) или все, что у вас есть. Но что делать/делать в отношении разрешений, которые я считаю более тонким контролем? Позвольте мне уточнить....

В моем сайте asp.net mvc у меня есть разные области, такие как администрирование, управление, обмен сообщениями, отчетность и т.д. Я бы создал роли для каждого из них, такие как "Администратор", "Менеджер", "Репортер" и т.д. Без соответствующей роли, вы не сможете получить доступ к этой области сайта. Поэтому я заблокировал бы все контроллеры с этим уровнем класса.

Но теперь возьмем одну область в качестве примера; обмен сообщениями и сказать, что я хотел иметь более тонкие разрешения на зерно для CRUD; создавать сообщения, просматривать/читать сообщения, редактировать сообщения, удалять сообщения и т.д.

Наконец, мой вопрос. Как лучше всего было бы реализовать это более тонкое зерно контроля? Один из подходов, который я вижу (не уверен, что он хороший), заключается в том, чтобы просто создать роли членства asp.net для всего. Поэтому я мог бы...

Messenger (роль широкого уровня), CreateMessage, ReadMessage, EditMessage, DeleteMessage.

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

Вы видите какие-либо проблемы с этим подходом? У вас есть идея?

Решение До сих пор

Я решил создать свою собственную схему и внедрить собственные поставщики членства и роли. Моя схема включает:

  • Пользователь
  • UserProfile
  • Разрешение
  • PermissionAssignment
  • Роль
  • RoleAssignment

Отправляйтесь на следующий день или два, но обновляйте дополнительную информацию, когда я получаю шанс.

Ответ 1

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

[Authorize(Entities.Message, Actions.Create)]
public ActionResult CreateMessage()

[Authorize(Entities.Message, Actions.Edit)]
public ActionResult EditMessage()

[Authorize(Entities.Message, Actions.View)]
public ActionResult ViewMessage()

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

РЕДАКТИРОВАТЬ: Чтобы обрабатывать определенные правила, такие как указатель Дэвид Роббинс, менеджеру A не разрешено удалять сообщения, созданные диспетчером B, при условии, что у них обоих есть необходимое разрешение для доступа к этому действию контроллера, Авторизатор не несет ответственности за проверку этого типа правил, и даже если вы попытаетесь проверить, что на уровне Action Filter это будет больно, то что вы можете сделать, это расширить проверку авторизации на ActionResult (вводя параметр действия, содержащий результат проверки), и пусть ActionResult делает там логическое решение со всеми аргументами.

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

Ответ 2

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

Если вы должны были создать роль для каждого действия - EditMessage, DeleteMessage - что вы будете делать в случае, когда Менеджер A НЕ должен удалять сообщения для менеджера B?

Ответ 3

Помимо добавления [Authorize(Roles="Administrator")] и т.д. над вашим контроллером. Вы также можете поместить этот атрибут в индивидуальные действия