Рекомендации по управлению доступом к полям формы

У меня есть классическое трехуровневое веб-приложение ASP.Net 3.5 с формами, которые отображают бизнес-объекты и позволяют их редактировать. Элементы управления в форме соответствуют свойству базового бизнес-объекта. Пользователь будет иметь права на чтение / запись, чтение или отсутствие доступа к различным элементам управления в зависимости от его / ее роли. Очень обычные вещи.

Мой вопрос: какова объектно-ориентированная лучшая практика для кодирования этого? Есть ли что-нибудь более элегантное, чем упаковка каждого элемента управления в тест на роль пользователя и установка его свойств Visible и Enabled?

Спасибо

15.12.2008 16:25:59
5 ОТВЕТОВ
РЕШЕНИЕ

Для правильной работы я обнаружил, что уровни доступа должны быть в этом возрастающем порядке: NONE, VIEW, REQUIRED, EDIT.

Обратите внимание, что REQUIRED НЕ является верхним уровнем, как вы могли бы подумать, так как EDIT (разрешение на заполнение и удаление) является большей привилегией, чем REQUIRED (разрешение только на заполнение).

Перечисление будет выглядеть так:

/** NO permissions.
 *     Presentation: "hidden"
 *     Database: "no access"
 */
NONE(0),

/** VIEW permissions.
 *     Presentation: "read-only"
 *     Database: "read access"
 */
VIEW(1),

/** VIEW and POPULATE permissions.
 *     Presentation: "required/highlighted"
 *     Database: "non-null"
 */
REQUIRED(2),

/** VIEW, POPULATE, and DEPOPULATE permissions.
 *     Presentation: "editable"
 *     Database: "nullable"
 */
EDIT(3);

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

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

Ветви:

1) Уровень представления МОЖЕТ скрыть поле (установить доступ к NONE) для поля базы данных, доступного только для чтения (VIEW).

2) Уровень представления НЕ МОЖЕТ отображать поле, когда бизнес-правила говорят, что пользователь не имеет по крайней мере доступа VIEW.

3) Уровень представления НЕ МОЖЕТ переместить доступ поля к «редактируемому» (обнуляемому), если база данных говорит, что это только «требуется» (не обнуляемому).

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

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

2
16.11.2009 17:43:23

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

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

0
15.12.2008 16:53:49

Моим первым инстинктом для выполнения этого в более OO-стиле было бы управление вашими ролями и их реализациями для этой цели (контроль прав на чтение / запись / и т. Д.), Это использование абстрактного шаблона фабрики для ваших ролей. Я буду рад объяснить вам все подробности того, о чем я говорю, если вы хотите, но в Интернете, вероятно, есть 900 примеров. Вот одна ссылка (отказ от ответственности: это мой блог, но в нем действительно говорится об использовании абстрактной фабрики специально для ролей)

Используя что-то подобное, вы могли бы затем использовать ряд методов для отображения правильных элементов управления для каждого из свойств вашего бизнес-объекта с правильными атрибутами (чтение / запись / скрытое / отображение / и т. Д.).

0
15.12.2008 17:11:29

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

Вам понадобится таблица для ваших основных высокоуровневых типов, для которых вы, вероятно, уже имеете предложения бизнес-объектов. Затем таблица для каждого статуса их. Затем таблица для полей этих классов. Затем таблица для пользовательских ролей (администратор, гость и т. Д.). Наконец, таблица для самих разрешений. В этой таблице будут столбцы для бизнес-класса, статуса, поля, роли пользователя и того, какие разрешения они имеют. Для разрешений я бы использовал одно поле и использовал перечисление: Hidden, ReadOnly, Editable и Required. Требуется подразумевает редактируемый. Все, кроме Скрытого, подразумевает Видимое. Наконец, поместите столбец «Приоритет» в эту таблицу, чтобы указать, какое разрешение используется, когда может применяться более одного.

Вы заполняете эту таблицу различными комбинациями класса, статуса, поля, роли и разрешения. Если значение равно нулю, оно применяется ко всем возможным значениям. Таким образом, вам не нужно триллион строк, чтобы покрыть все ваши базы. Например, в 99% случаев гостевые пользователи являются пользователями только для чтения. Таким образом, вы можете поместить в таблицу одну запись с указанием только роли «Гость», все остальное - «ноль», установить приоритет «высокий и высокий» и установить разрешение «Только чтение». Теперь для всех классов, всех статусов, всех полей, если пользователь является гостем, они будут иметь разрешение только для чтения.

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

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

Теперь, я подозреваю, вышесказанное удовлетворит 90% ваших потребностей.

Одна область, которая должна быть обработана в коде, если только вы не хотите стать по-настоящему модной, - это случаи, когда разрешение пользователя частично определяется значением полей в самом объекте . Допустим, у вас есть класс Project, в котором есть класс Project Manager. Теперь поле Percent Complete класса в основном доступно только для чтения всем, кроме менеджера проекта. Как вы собираетесь справиться с этим? Вам нужно будет предоставить способ включения определенных экземпляров класса в процесс принятия решений. Я делаю это в коде.

4
15.12.2008 18:08:39

Для меню веб-сайта мы можем использовать различные меню в зависимости от роли пользователя с помощью файлов Sitemap. Для элементов управления, таких как кнопки, нам придется скрывать их, используя свойство Visible. Я думаю, что хорошей идеей будет создание серверного элемента управления (Button) и предоставление свойства Role. Это позволит скрыть кнопку, если пользователь не в нужной роли.

0
15.12.2008 21:19:06