Как лучше обрабатывать разрешения (а не роли) в членстве 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")]
и т.д. над вашим контроллером. Вы также можете поместить этот атрибут в индивидуальные действия