Элегантный пользовательский интерфейс ASP.Net MVC и авторизация ModelBinder

Мы знаем, что авторизация — это сквозная проблема, и мы делаем все возможное, чтобы избежать слияния бизнес-логики в наших представлениях.

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


Пример

Форма: создание продукта

Поля:

  • Имя
  • Цена
  • Скидка

Роли:

  • Администратор ролей

    • Is allowed to see and modify the Name field
    • Разрешено видеть и изменять поле «Цена»
    • Разрешено видеть и изменять Скидку
  • Помощник администратора роли

    • Is allowed to see and modify the Name
    • Разрешено видеть и изменять цену

Fields, отображаемые в каждой роли, различаются, также model binding необходимо игнорировать discount field для роли "помощник администратора".

Как бы вы это сделали?


person SDReyes    schedule 29.04.2010    source источник
comment
Вы используете EditorFor() для своих экранов?   -  person John Farrell    schedule 29.04.2010
comment
Еще нет. Я использую MVC 1 (миграция запланирована;) почему?   -  person SDReyes    schedule 29.04.2010
comment
Потому что это намного проще с шаблонными хелперами и метаданными модели.   -  person John Farrell    schedule 29.04.2010


Ответы (3)


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

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

person JoseMarmolejos    schedule 29.04.2010
comment
Привет, Хосе, в контексте MVC я согласен с вами по поводу включения логики UI и ModelBinding в контроллеры. (у них есть доступ ко всем нужным нам компонентам, к тому же для этих случаев уже существуют кастомные ModelBinders). Хороший подход +1 - person SDReyes; 30.04.2010

Я мог подумать, что для этого нужно создать свои собственные версии введите методы расширения. Например, вместо TextBox вы можете создать TextBoxRoles и определить его следующим образом:

public static MvcHtmlString TextBoxRoles(
    this HtmlHelper htmlHelper,
    string name,
    string RolesEdit,
    string RolesView
)

Тогда в коде это будет выглядеть так:

<%= Html.TextBoxRoles("Price", "Administrator","Administrator,Assistant") %>

Затем ваша реализация TextBoxRoles будет проверять роли текущего пользователя через User.IsInRole(), чтобы определить, что должно отображаться на странице.

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

person Keltex    schedule 29.04.2010
comment
Привет, Keltex, хороший обходной путь +1!, тем не менее, используя этот подход, вам все равно придется определять роли авторизации в ваших представлениях: |. Интересно, можем ли мы перенести всю эту логику на другой уровень. Как вы думаете? Еще раз спасибо Келтекс! : Д - person SDReyes; 29.04.2010

А как насчет LinFu, фреймворка АОП? Если это сквозное, то объявите, что это так, и относитесь к нему как к таковому.

person Scott Hanselman    schedule 29.04.2010
comment
Привет, Скотт, АОП выглядит очень хорошим подходом +1, спасибо! вы имеете в виду что-то вроде перехвата методов рендеринга у хелперов и добавления логики авторизации? - person SDReyes; 29.04.2010